有条件地在新样式类中实现__iter__ [英] Conditionally implementing __iter__ in new style classes

查看:85
本文介绍了有条件地在新样式类中实现__iter__的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试在抽象基类上实现__iter__而我不知道b
知道子类是否支持。

希望有意义如果没有,这段代码应该更清楚:


类基数:

def __getattr __(自我,名字):

如果name ==" __ iter __"和hasattr(self,Iterator):

返回self.Iterator

引发AttributeError,名称


class Concrete(基数):

def Iterator(个体经营):

收益率1

收益率2

收益率3

这个想法是,如果Base的子类定义了''Iterator''方法,那么
实例是可迭代的。否则它们是不可迭代的。


上面给出了预期的行为:iter(Base())引发了一个

TypeError:迭代非序列 ;和iter(Concrete())返回一个

生成器。


但是,如果我将Base设为newstyle类,那么这将不起作用

更长。 __getattr__永远不会被称为__ iter __ (既不是

__getattribute __,顺便说一句)。可能这与数据描述符

和非数据描述符有关,但是我现在太累了以至于认为

更进一步。


有什么方法可以让上面的代码与新风格一起工作

课程?


谢谢,


Thomas

I''m trying to implement __iter__ on an abstract base class while I don''t
know whether subclasses support that or not.
Hope that makes sense, if not, this code should be clearer:

class Base:
def __getattr__(self, name):
if name == "__iter__" and hasattr(self, "Iterator"):
return self.Iterator
raise AttributeError, name

class Concrete(Base):
def Iterator(self):
yield 1
yield 2
yield 3

The idea is that if a subclass of Base defines an ''Iterator'' method,
instances are iterable. They are not iterable otherwise.

The above gives the expected behaviour: iter(Base()) raises a
"TypeError: iteration over non-sequence", and iter(Concrete()) returns a
generator.

If, however, I make Base a newstyle class, this will not work any
longer. __getattr__ is never called for "__iter__" (neither is
__getattribute__, btw). Probably this has to do with data descriptors
and non-data descriptors, but I''m too tired at the moment to think
further about this.

Is there any way I could make the above code work with new style
classes?

Thanks,

Thomas

推荐答案

Thomas Heller< th ***** @ python.net>写道:
Thomas Heller <th*****@python.net> writes:
我正在尝试在抽象基类上实现__iter__而我不知道子类是否支持它。
希望这是有道理的,如果没有,这段代码应该更清楚:

类基:
def __getattr __(self,name):
如果name ==" __ iter __"和hasattr(self,Iterator):
返回self.Iterator
引发AttributeError,名称

类Concrete(Base):
def Iterator(self) :
产量1
产量2
产量3

想法是,如果Base的子类定义了''Iterator''方法,
实例是可迭代的。否则它们是不可迭代的。

上面给出了预期的行为:iter(Base())引发了一个
TypeError:迭代非序列和iter(Concrete())返回一个
生成器。

但是,如果我将Base设为newstyle类,那么这将不会更长。 __getattr__永远不会被称为__ iter __ (既不是__getattribute__,顺便说一句)。可能这与数据描述符和非数据描述符有关,但我现在太累了以至于对此进一步思考。

有什么办法吗?我可以使上面的代码适用于新风格的类吗?
I''m trying to implement __iter__ on an abstract base class while I don''t
know whether subclasses support that or not.
Hope that makes sense, if not, this code should be clearer:

class Base:
def __getattr__(self, name):
if name == "__iter__" and hasattr(self, "Iterator"):
return self.Iterator
raise AttributeError, name

class Concrete(Base):
def Iterator(self):
yield 1
yield 2
yield 3

The idea is that if a subclass of Base defines an ''Iterator'' method,
instances are iterable. They are not iterable otherwise.

The above gives the expected behaviour: iter(Base()) raises a
"TypeError: iteration over non-sequence", and iter(Concrete()) returns a
generator.

If, however, I make Base a newstyle class, this will not work any
longer. __getattr__ is never called for "__iter__" (neither is
__getattribute__, btw). Probably this has to do with data descriptors
and non-data descriptors, but I''m too tired at the moment to think
further about this.

Is there any way I could make the above code work with new style
classes?




我忘了提这个:Base类也实现了一个__getitem__

方法,如果

子类中的.Iterator方法不可用,则应该用于迭代。因此,如果找不到.Iterator,似乎不可能在__iter__方法中引发异常

- __iter__必须返回

迭代器(如果存在)。

Thomas



I forgot to mention this: The Base class also implements a __getitem__
method which should be used for iteration if the .Iterator method in the
subclass is not available. So it seems impossible to raise an exception
in the __iter__ method if .Iterator is not found - __iter__ MUST return
an iterator if present.

Thomas


>我正在尝试在抽象基类上实现__iter__而我
> I''m trying to implement __iter__ on an abstract base class while I
不知道子类是否支持它。
希望有意义,如果不是,这段代码应该更清楚:

类基:
def __getattr __(self,name):
如果name ==" __ iter __"和hasattr(self,Iterator):
返回self.Iterator
引发AttributeError,名称

类Concrete(Base):
def Iterator(self) :
产量1
产量2
产量3
don''t
know whether subclasses support that or not.
Hope that makes sense, if not, this code should be clearer:

class Base:
def __getattr__(self, name):
if name == "__iter__" and hasattr(self, "Iterator"):
return self.Iterator
raise AttributeError, name

class Concrete(Base):
def Iterator(self):
yield 1
yield 2
yield 3




我不知道如何实现它,但为什么要'你只需使用


类底座:

通过


类混凝土(基础):

def __iter __(个体经营):

收益率1

收益率2

收益率3

什么有一个基本类实际上有一个方法重命名__iter__ ==>迭代器?


- 哈罗德 -


-

永远记住你是独一无二的;

就像其他人一样。

-



I don''t know how to achieve it, but why don''t you simply use

class Base:
pass

class Concrete(Base):
def __iter__(self) :
yield 1
yield 2
yield 3
What is the advantage to have a baseclass that essentially does
some method renaming __iter__ ==> Iterator?

- harold -

--
Always remember that you are unique;
just like everyone else.
--


我不确定我明白为什么你想要至。只是没有在你的新课程中定义

__iter__,你会得到预期的行为。

I''m not sure I understand why you would want to. Just don''t define
__iter__ on your newstyle class and you''ll get the expected behavior.


这篇关于有条件地在新样式类中实现__iter__的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆