2009-04-11 12 views
14

Data una classe che mantiene un registro dei suoi oggetti:iterazione di oggetto istanze di una data classe in Python

class Person(object): 
    __registry = [] 

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

Come faccio a fare i seguenti lavori di codice (senza l'utilizzo di persona .__ registro):

Durante le ricerche ho trovato un suggerimento che si potrebbe andare per un __metaclass__ con un metodo __getitem__. Qualche idea su come sarebbe?

+0

ehh non fare un brutto schermaglia sembrare carino. –

risposta

20

È possibile rendere iterable l'oggetto della classe con un metaclass semplice.

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 

(ho anche cambiato __registry per _registry per rendere più facile l'accesso dal metaclasse). Quindi,

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

grazie mille ... era esattamente quello che stavo cercando;) – Titusz

+0

Un consiglio davvero carino: non lo sapevo :) – jkp

+0

Perché non funziona solo inserendo il def __iter__ nella classe Person? Mi stavo solo chiedendo. –

2

si può fare con:

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

questo è ovvio ... ma mi piacerebbe farlo funzionare come: per l'oggetto in Classname ... (solo per la sua bellezza ...) – Titusz

+0

devi rendere la tua classe iterabile allora, credo che sia – SilentGhost

+0

e non lo sia beautiful btw, – SilentGhost

10

In primo luogo, non usare doppi __ nomi. Sono riservati per l'uso da Python. Se vuoi "privato" usa il singolo _.

In secondo luogo, mantenere questo tipo di cose il più semplice possibile. Non sprecare un sacco di tempo ed energie su qualcosa di complesso. Questo è un problema semplice, mantenere il codice il più semplice possibile per portare a termine il lavoro.

class Person(object): 
    _registry = [] 

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

for p in Person._registry: 
    print p 
+0

Il punto è che la soluzione _registry * è * il modo più semplice possibile per farlo. Qualcos'altro sta solo cercando di "mettere il rossetto su un maiale". –

Problemi correlati