【问题标题】:Iterating over object instances of a given class in Python在 Python 中迭代给定类的对象实例
【发布时间】:2009-04-11 11:13:09
【问题描述】:

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

class Person(object):
   __registry = []

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

如何使以下代码工作(不使用 Person.__registry):

for personobject in Person:
    print personobject

在研究时,我发现了一个提示,可以使用 __getitem__ 方法来选择 __metaclass__。有什么想法吗?

【问题讨论】:

  • 呃,不要让丑陋的黑客看起来很漂亮。

标签: python oop


【解决方案1】:

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

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

(我还将__registry 更改为_registry 以便更容易从元类访问)。 那么,

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

【讨论】:

  • 非常感谢...这正是我想要的 ;)
  • 非常好的提示:我不知道这个:)
  • @Paolo 将 iter 放入 Person 类使 Person 实例可迭代,将其放入元类使 Person 类本身可迭代,这正是我们想要的。
  • 嗨,我已经在 Python 3.6.0 Anaconda 64 位中测试了这段代码,但它不起作用。我修复了打印语句,但你得到一个 TypeError: 'type' object is not iterable。我是 Python 的新手,但我想这可能是因为可迭代对象的规范在 Python 3.6 中已更改。
  • _registery 不会在您删除类的实例时得到更新。
【解决方案2】:

首先,不要使用双 __ 名称。它们保留供 Python 使用。如果你想“私人”使用单个_

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

class Person(object):
    _registry = []

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

for p in Person._registry:
    print p

【讨论】:

  • 重点是_registry 解决方案 最简单的方法。其他任何事情都只是试图“给猪涂口红”。
【解决方案3】:

你可以这样做:

for item in Person.__registry:
    print(item)

【讨论】:

  • 这很明显......但我想让它像:类名中的项目......(只是为了它的美丽......)
  • 我猜你需要让你的类可迭代
猜你喜欢
  • 2015-11-28
  • 2017-05-05
  • 1970-01-01
  • 2020-02-12
  • 2019-04-26
  • 2021-01-07
  • 2013-09-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多