Dada una clase que mantiene un registro de sus objetos:
class Person(object): __registry = [] def __init__(self, name): self.__registry.append(self) self.name = name
¿Cómo puedo hacer que funcione el siguiente código (sin usar el registro de la Persona .__)?
for personobject in Person: print personobject
Mientras investigaba, encontré un indicio de que uno podría ir a una __metaclass__
con un __getitem__
-mod. ¿Alguna idea de cómo se vería esto?
Puedes hacer que tu objeto de clase sea iterable con una simple metaclase.
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
(También he cambiado __registry
a _registry
para facilitar el acceso desde la metaclase). Entonces,
>>> p = Person('John') >>> p2 = Person('Mary') >>> for personobject in Person: ... print personobject ...
En primer lugar, no utilice nombres __
dobles. Están reservados para su uso por Python. Si quieres “privado” usa solo _
.
Segundo, mantén este tipo de cosas lo más simple posible. No pierdas mucho tiempo y energía en algo complejo. Este es un problema simple, mantenga el código lo más simple posible para realizar el trabajo.
class Person(object): _registry = [] def __init__(self, name): self._registry.append(self) self.name = name for p in Person._registry: print p
Puedes hacerlo con:
for item in Person.__registry: print(item)