2009-04-11 6 views
14

Dada una clase que mantiene un registro de sus objetos:interactuando sobre instancias de objetos de una clase dada en Python

class Person(object): 
    __registry = [] 

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

¿Cómo puedo hacer el trabajo siguiente código (sin usar Persona .__ registro):

for personobject in Person: 
    print personobject 

Mientras investigaba, encontré una pista de que se podía obtener un __metaclass__ con un __getitem__ -metodo. ¿Alguna idea de cómo se vería esto?

+0

ehh no hagas que un feo hack se vea bonito. –

Respuesta

20

Puede hacer que su objeto de clase sea iterable con una metaclase simple.

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 

(que también han cambiado __registry a _registry para hacer más fácil el acceso de la metaclase). Luego,

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

muchas gracias ... eso era exactamente lo que estaba buscando;) – Titusz

+0

Consejo realmente bueno: No sabía esto :) – jkp

+0

¿Por qué no funciona con solo poner el def __iter__ en la clase Person? Sólo me preguntaba. –

2

se puede hacer con:

for item in Person.__registry: 
    print(item) 
+0

eso es obvio ... pero me gustaría hacer que funcione como: para el elemento en Nombre de clase ... (solo por la belleza de ello ...) – Titusz

+0

necesita hacer que su clase sea iterable, supongo – SilentGhost

+0

y no es hermoso por cierto, – SilentGhost

10

En primer lugar, no utilizan dobles __ nombres. Están reservados para su uso por Python. Si desea un uso "privado" solo _.

En segundo lugar, mantenga este tipo de cosas tan simple como sea posible. No pierdas mucho tiempo y energía en algo complejo. Este es un problema simple, mantenga el código tan simple como sea posible para hacer el trabajo.

class Person(object): 
    _registry = [] 

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

for p in Person._registry: 
    print p 
+0

El punto es que la solución _registry * es * la forma más simple posible de hacer esto. Todo lo demás es simplemente tratar de "poner lápiz labial en un cerdo". –

Cuestiones relacionadas