Skip to main content
 首页 » 编程设计

python之在构造函数中分配了 __iter__ 的类未被识别为迭代器

2025年05月04日10haluo1

关于迭代器的一个奇怪问题。在调查另一个问题时,我发现了以下内容。这是一个有效的迭代器:

class CacheGen(object): 
    def __init__(self, iterable): 
        if isinstance(iterable, (list, tuple, dict)): 
            self._myiter = iterable 
        else: 
            self._myiter = list(iterable) 
    def __iter__(self): 
        return self._myiter.__iter__() 
    def __contains__(self, key): 
        return self._myiter.__contains__(key) 
    def __getitem__(self, key): 
        return self._myiter.__getitem__(key) 

这是一个类似的可迭代对象,但它没有:

class CacheGen2(object): 
    def __init__(self, iterable): 
        if isinstance(iterable, (list, tuple, dict)): 
            self._myiter = iterable 
        else: 
            self._myiter = list(iterable) 
        self.__iter__ = self._myiter.__iter__ 
        self.__contains__ = self._myiter.__contains__ 
        self.__getitem__ = self._myiter.__getitem__ 

请注意,它们实际上在做同样的事情,但是一个委托(delegate),另一个只是将我的类构造函数分配给列表。任何想法为什么?请注意,它在类中有一个 iter 函数,我可以直接调用它并获得一个有效的迭代器,但“普通”函数不起作用。

xr = xrange(100) 
cg = CacheGen(xr) 
list(cg) 
[0,1,2,3... 
 
cg2 = CacheGen2(xr) 
list(cg2) 
TypeError                                 Traceback (most recent call last) 
<ipython-input-83-1f4da2c55acb> in <module>() 
----> 1 list(cg2) 
 
TypeError: 'CacheGen2' object is not iterable 
 
cg2.__iter__ 
<method-wrapper '__iter__' of list object at 0x0000000006695C08> 
 
cg2.__iter__() 
<listiterator at 0x669c438> 
 
iter(cg2) 
TypeError                                 Traceback (most recent call last) 
<ipython-input-86-b62853ce1dab> in <module>() 
----> 1 iter(cg2) 
 
TypeError: 'CacheGen2' object is not iterable 

请您参考如下方法:

像__iter__ 这样的魔术方法是在类中查找的,而不是在实例中查找的,因此将它们分配给self 是行不通的。它们必须实际存在于类里面。