Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/277.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 类型错误:';类型';对象不可编辑-在对象实例上迭代_Python_Iterable - Fatal编程技术网

Python 类型错误:';类型';对象不可编辑-在对象实例上迭代

Python 类型错误:';类型';对象不可编辑-在对象实例上迭代,python,iterable,Python,Iterable,我正在做一个项目,我想让我的一门课变得更适合我。就我所知,我可以通过使用元类来做到这一点 首先,我想了解元类是如何工作的。因此,我想提出我自己的实践例子,我做了一个汽车类。所以在这里,我想让我的Car类对象是可移植的,然后我想在main函数中打印它们的名称 代码示例如下所示: __author__ = 'mirind4' class IterableCar(type): def __iter__(self): return iter(self.__name__) cl

我正在做一个项目,我想让我的一门课变得更适合我。就我所知,我可以通过使用元类来做到这一点

首先,我想了解元类是如何工作的。因此,我想提出我自己的实践例子,我做了一个汽车类。所以在这里,我想让我的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: 'type' object is not iterable
您能告诉我代码中的错误在哪里吗?到目前为止,我已经在这个网站和互联网上检查了类似的问题,但我不知道问题是什么。我正在使用python 3.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

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

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

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

    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的类都将自动跟踪其实例

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

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

对于车内的车辆,您有
。汽车是一种阶级定义。你期望它做什么?你的意思是把
car1
car2
放在一个列表中,然后重复这个列表吗?(我知道你的问题的顶部有一些关于“使一个类变得可移植”的东西,但不清楚你想要什么。
Car
似乎并不代表任何类型的集合。)@Two-bitalchest——我想OP希望它产生
C-a-R
。。。制作一个iterable类是一个有趣的概念…@mgilson实际上我猜OP希望它返回到目前为止创建的每个实例,我怀疑这是可能的,但我们将看到。在Python 3中,您使用
类Car(metaclass=IterableCar)
定义一个元类,不使用
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu是的,weakref.WeakSet可能是其中最容易使用的对象,在这里可能会有所帮助,但我认为这超出了这个问题的范围。。。(因为我们甚至都不知道OP想要做什么…@DanD。--更新为
WeakSet
@DanD。不幸的是,我不明白为什么没有weakref模块的程序会出现内存泄漏问题。垃圾收集器在这种情况下不工作吗?老实说,我对这个话题还是有点初学者,对此我很抱歉。你能给我一个简短的解释吗?(我知道什么是内存泄漏,但我不知道它在mgilson的代码中的位置)。非常感谢@mirind4——如果在类级别保留实例列表,那么每次创建的实例都会有一个引用。因此,引用计数永远不会下降到0,因此对象将永远无法被垃圾收集。这可能是你想要的行为。使用
WeakSet
,当一个对象超出范围时,它将被垃圾收集,类将停止跟踪它。现在,如果你只是把它作为修复“内存泄漏”的薄弱环节,那么你就万事大吉了:-)。而且,为了完整起见,我想你还需要添加
\uuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuuu