在Python中迭代给定类的对象实例

Tit*_*usz 16 python oop

给定一个保持其对象注册表的类:

class Person(object):
   __registry = []

   def __init__(self, name):
       self.__registry.append(self)
       self.name = name
Run Code Online (Sandbox Code Playgroud)

如何使以下代码工作(不使用Person .__注册表):

for personobject in Person:
    print personobject
Run Code Online (Sandbox Code Playgroud)

在研究的过程中,我发现了一个人可以选择__metaclass__一种__getitem__方法的暗示.任何想法如何看起来像?

dF.*_*dF. 24

您可以使用简单的元类使您的类对象可迭代.

class IterRegistry(type):
    def __iter__(cls):
        return iter(cls._registry)

class Person(object):
    __metaclass__ = IterRegistry
    _registry = []

    def __init__(self, name):
        self._registry.append(self)
        self.name = name
Run Code Online (Sandbox Code Playgroud)

(我也改变了__registry,以_registry使它更容易从元类访问).然后,

>>> p = Person('John')
>>> p2 = Person('Mary')
>>> for personobject in Person:
...     print personobject
...
<person.Person object at 0x70410>
<person.Person object at 0x70250>
Run Code Online (Sandbox Code Playgroud)

  • 嗨,我已经在 Python 3.6.0 Anaconda 64 位中测试了这段代码,但它不起作用。我修复了打印语句,但你得到一个 TypeError: 'type' object is not iterable。我是 Python 新手,但我想这可能是因为可迭代对象的规范在 Python 3.6 中已更改。 (3认同)
  • @Paolo 将 __iter__ 放在 Person 类中会使 Person 实例可迭代,将它放在元类中会使 Person 类本身可迭代,这就是我们在这里想要的。 (2认同)

S.L*_*ott 11

首先,不要使用双重__名称.它们保留供Python使用.如果你想"私人"使用单身_.

其次,保持这种事情尽可能简单.不要在复杂的事情上浪费大量的时间和精力.这是一个简单的问题,让代码尽可能简单,以完成工作.

class Person(object):
    _registry = []

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

for p in Person._registry:
    print p
Run Code Online (Sandbox Code Playgroud)

  • 关键是 _registry 解决方案*是*最简单的方法。其他任何事情都只是想“给猪涂口红”。 (2认同)