gpt4 book ai didi

python - 使用 __iter__ 迭代类实例

转载 作者:行者123 更新时间:2023-11-30 23:14:36 24 4
gpt4 key购买 nike

我想将一个类的所有实例存储在一个列表中,并想对其进行迭代。

我尝试了以下两种方法:

1 使用元类

class ClassIter(type):
def __iter__(cls):
return iter(cls._ClassRegistry)
def __len__(cls):
return len(cls._ClassRegistry)

class MyClass(object):
__metaclass__ = ClassIter
_ClassRegistry = []
def __init__(self,objname):
self._ClassRegistry.append(self)
self.name = objname

for x in ["first", "second", "third"]:
MyClass(x)

for y in MyClass:
print y.name

2:在类本身中使用iter

class MyClass1(object):
_ClassRegistry = []
def __init__(self,objname):
self._ClassRegistry.append(self)
self.name = objname
def __iter__(self):
return iter(self._ClassRegistry)

for x in ["first", "second", "third"]:
MyClass1(x)

for y in MyClass1:
print y.name

在这两种解决方案中,前一种方法工作完美,而后一种解决方案给出错误 TypeError: 'type' object is not iterable

有人可以(详细)解释一下为什么第二种方法不起作用以及为什么需要使用元类来使另一个类可迭代?

最佳答案

__iter__这样的特殊方法不会直接在对象上查找,而是在对象的类型上查找。 Python 调用 type(object).__iter__(object),而不是 object.__iter__(),有效地绕过了正常的先对象后类型查找(因此从实例到类以及从类到元类)。

这样做是为了使类型的散列成为可能;如果 hash(object) 使用直接在对象上找到的 __hash__ 方法,则您永远无法为实例定义具有 __hash__ 方法的自定义类.

元类是类的类型;就像类是实例的类型一样,所以 iter(class) 查找 type(class).__iter__() 而不是 class.__iter__ 直接。

如果确实按照这种方式工作,那么您永远无法为类实例定义__iter__方法,因为class.__iter__ 将是一个方法,需要绑定(bind)实例,而如果您迭代该类,则没有这样的实例。

请参阅Special method lookup section Python 数据模型文档:

For custom classes, implicit invocations of special methods are only guaranteed to work correctly if defined on an object’s type, not in the object’s instance dictionary.

关于python - 使用 __iter__ 迭代类实例,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28676399/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com