Python 类型错误:“类型”对象不可迭代 - 迭代对象实例

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/32362148/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-19 11:25:28  来源:igfitidea点击:

TypeError: 'type' object is not iterable - Iterating over object instances

pythoniterable

提问by mirind4

I am working on a project and I would like to make one of my classes iterable. To the best of my knowledge I can do that with using metaclass.

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

First of all I would like to understand how metaclass works. Therefore I would like to present my own practicing example where I made a Car class. So here I would like to make my Car class objects iterable then I would like to print the names of them in the main function.

首先,我想了解元类是如何工作的。因此,我想展示我自己的练习示例,其中我制作了 Car 课程。所以在这里我想让我的 Car 类对象可迭代,然后我想在主函数中打印它们的名称。

The code example is the following:

代码示例如下:

__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)

But unfortunately I got an TypeError:

但不幸的是我得到了一个类型错误:

TypeError: 'type' object is not iterable

Would you be so kind as to tell me where I do the mistake in my code? So far I have checked similar problem-questions over this site and internet but I do not know what the problem is. I am using python 3.4. Thanks in advance!

你能不能告诉我我的代码哪里出错了?到目前为止,我已经通过这个网站和互联网检查了类似的问题,但我不知道问题是什么。我正在使用 python 3.4。提前致谢!

采纳答案by mgilson

As far as I can tell, making a class object iterable by using a metaclass works just fine:

据我所知,通过使用元类使类对象可迭代工作得很好:

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)

Results in:

结果是:

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


Here's an example where I actually track the cars generated:

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

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)

Note that if you're using python3.x, to use a metaclass you do:

请注意,如果您使用的是 python3.x,要使用元类,请执行以下操作:

class Car(metaclass=IterableCar):
    ...

Rather than:

而不是:

class Car(object):
    __metaclass__ = IterableCar

which likely explains the problem that you're experiencing.

这可能解释了您遇到的问题。

回答by chepner

To track instances of the class that are created, we'll start by adding a _carsattribute to each the class created by the metaclass. This will be set of weak references, so that the class itself does not prevent unused instances from being garbage-collected.

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

class IterableCar(type):
    def __new__(meta, name, bases, attrs):
        attrs['_cars'] = weaker.WeakSet()
        return type.__new__(meta, name, bases, attrs)

To add the instances, we'll override __call__. Essentially, this is where you put code that you would ordinarily put in __new__or __init__when defining the class itself.

要添加实例,我们将覆盖__call__. 本质上,这是您放置通常放置的代码__new____init__在定义类本身时放置的位置。

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

And to make the class iterable by iterating over its set of instances,

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

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

Any class using IterableCarwill automatically track its instances.

任何使用的类IterableCar都会自动跟踪它的实例。

class Car(metaclass=IterableCar):
    def __init__(self, name):
        self.name = name

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