我正在开发一个项目,我想让我的一个类可迭代。据我所知,我可以使用元类来做到这一点。
首先,我想了解元类的工作原理。因此,我想提出自己的实践例子,我在那里开了一个汽车课。所以在这里我想让我的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。 提前谢谢!
答案 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,))
后,一切都开始正常了。