Перебор экземпляров объекта данного класса в Python - PullRequest
16 голосов
/ 11 апреля 2009

Учитывая класс, который ведет реестр своих объектов:

class Person(object):
   __registry = []

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

Как заставить работать следующий код (без использования реестра Person .__):

for personobject in Person:
    print personobject

Во время исследования я обнаружил подсказку, что можно пойти на __metaclass__ с __getitem__ -методом. Любые идеи, как это будет выглядеть?

Ответы [ 3 ]

22 голосов
/ 11 апреля 2009

Вы можете сделать свой объект класса итеративным с помощью простого метакласса.

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>
11 голосов
/ 11 апреля 2009

Во-первых, не используйте двойные __ имена. Они зарезервированы для использования Python. Если вы хотите "частный", используйте сингл _.

Во-вторых, делайте подобные вещи максимально простыми. Не тратьте много времени и сил на что-то сложное. Это простая проблема, сделайте код максимально простым, чтобы выполнить работу.

class Person(object):
    _registry = []

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

for p in Person._registry:
    print p
2 голосов
/ 11 апреля 2009

Вы можете сделать это с:

for item in Person.__registry:
    print(item)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...