TypeError:' type' object不可迭代 - 迭代对象实例

时间:2015-09-02 20:05:44

标签: python iterable

我正在开发一个项目,我想让我的一个类可迭代。据我所知,我可以使用元类来做到这一点。

首先,我想了解元类的工作原理。因此,我想提出自己的实践例子,我在那里开了一个汽车课。所以在这里我想让我的Car类对象可迭代,然后我想在main函数中打印它们的名字。

代码示例如下:

__author__ = 'mirind4'

class IterableCar(type):
    def __iter__(self):
        return iter(self.__name__)

class Car(object):
    __metaclass__ = IterableCar

    def __init__(self, name):
        self.name = name


if __name__=='__main__':

    car1 = Car('Mercedes')
    car2 = Car('Toyota')
    for cars in Car:
        print (cars.name)

但不幸的是我得到了一个TypeError:

TypeError: 'type' object is not iterable

您是否愿意告诉我我的代码中的错误在哪里?到目前为止,我已经检查过这个网站和互联网上的类似问题,但我不知道问题是什么。我正在使用python 3.4。 提前谢谢!

3 个答案:

答案 0 :(得分:4)

据我所知,使用元类使一个类对象可迭代正常工作:

from __future__ import print_function

class IterableCar(type):
    def __iter__(cls):
        return iter(cls.__name__)

class Car(object):
    __metaclass__ = IterableCar

    def __init__(self, name):
        self.name = name


if __name__=='__main__':

    car1 = Car('Mercedes')
    car2 = Car('Toyota')
    for cars in Car:
        print (cars)

结果:

mgilson$ python ~/sandbox/test.py 
C
a
r

以下是我实际跟踪生成的汽车的示例:

from __future__ import print_function
import weakref

class IterableCar(type):

    _cars = weakref.WeakSet()

    def __iter__(cls):
        return iter(cls._cars)

    def add_car(cls, car):
        cls._cars.add(car)


class Car(object):
    __metaclass__ = IterableCar

    def __init__(self, name):
        self.__class__.add_car(self)
        self.name = name


if __name__=='__main__':

    car1 = Car('Mercedes')
    car2 = Car('Toyota')
    for cars in Car:
        print (cars.name)

请注意,如果您正在使用python3.x,那么您可以使用元类:

class Car(metaclass=IterableCar):
    ...

而不是:

class Car(object):
    __metaclass__ = IterableCar

可能会解释您遇到的问题。

答案 1 :(得分:2)

要跟踪创建的类的实例,我们首先为每个由元类创建的类添加willTransitionTo属性。这将是一组弱引用,因此类本身不会阻止未使用的实例被垃圾回收。

_cars

要添加实例,我们将覆盖class IterableCar(type): def __new__(meta, name, bases, attrs): attrs['_cars'] = weaker.WeakSet() return type.__new__(meta, name, bases, attrs) 。从本质上讲,这是您在定义类本身时放置通常放在__call____new__中的代码的位置。

__init__

通过遍历其实例集来使类可迭代,

    def __call__(cls, *args, **kwargs):
        rv = type.__call__(cls, *args, **kwargs)
        cls._cars.add(rv)
        return rv

使用 def __iter__(self): return iter(self._cars) 的任何课程都会自动跟踪其实例。

IterableCar

答案 2 :(得分:0)

当装饰器需要一个元组并且我传入一个没有尾随逗号的元素时,我出现了这个错误。

@api_view(["GET"])
@authentication_classes((CustomAuthentication,))
@permission_classes((AdminPermission))
def order_attached_documents_from_order_uuid(request):
    # ...
    return Response(status=status.HTTP_200_OK)

在我将 @permission_classes((AdminPermission)) 更改为 @permission_classes((AdminPermission,)) 后,一切都开始正常了。