2013-11-01 31 views
7

Sotto, base_id e _id è una variabile di classe e condivisa tra tutte le classi figlio.
C'è un modo per separarli in ogni classe?sostituisce la variabile di classe in python?

from itertools import count 

class Parent(object): 
    base_id = 0 
    _id = count(0) 

    def __init__(self): 
     self.id = self.base_id + self._id.next() 


class Child1(Parent): 
    base_id = 100 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child1:', self.id 

class Child2(Parent): 
    base_id = 200 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child2:', self.id 

c1 = Child1()     # 100 
c2 = Child2()     # 201 <- want this to be 200 
c1 = Child1()     # 102 <- want this to be 101 
c2 = Child2()     # 203 <- want this to be 201 
+0

C'è qualche motivo particolare per cui si desidera che le centinaia di cifre rappresentino la classe? Che dire se ottieni più di 100 istanze? Quindi avrai sovrapposizioni. Dove vedrai l'ID e potrebbe esserci un modo migliore per distinguere le classi dall'usare l'ID? (Forse potresti visualizzare alcune informazioni extra, per esempio.) – jpmc26

+1

Questo non importa in questo caso; anche se eugene ha cambiato ID in tuple di 2 (ad esempio (1,0), (1,1), (1,2) ... per 'Child1') rimane il problema di creare contatori indipendenti. –

risposta

3

Se non si vuole violare il principio DRY come falsetru suggerisce, avrete bisogno di utilizzare metaclassi. Stavo pensando di scrivere qualcosa, ma there's already a good long description of metaclasses on SO, quindi dai un'occhiata.

I metaclassi, in breve, consentono di controllare la creazione di sottoclassi.

Fondamentalmente, è necessario creare una sottoclasse di Parent, aggiungere il membro _id alla sottoclasse appena creata.

2

Come ha detto nella domanda, _id è condiviso da classi genitore e tutti i bambini. Definisci _id per ogni classe di bambini.

from itertools import count 

class Parent(object): 
    base_id = 0 
    _id = count(0) 

    def __init__(self): 
     self.id = self.base_id + self._id.next() 


class Child1(Parent): 
    base_id = 100 
    _id = count(0) # <------- 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child1:', self.id 

class Child2(Parent): 
    base_id = 200 
    _id = count(0) # <------- 
    def __init__(self): 
     Parent.__init__(self) 
     print 'Child2:', self.id 

c1 = Child1()     # 100 
c2 = Child2()     # 200 
c1 = Child1()     # 101 
c2 = Child2()     # 201 

UPDATE

Utilizzando metaclasse:

class IdGenerator(type): 
    def __new__(mcs, name, bases, attrs): 
     attrs['_id'] = count(0) 
     return type.__new__(mcs, name, bases, attrs) 

class Parent(object): 
    __metaclass__ = IdGenerator 
    base_id = 0 
    def __init__(self): 
     self.id = self.base_id + next(self._id) 
4

Se avete veramente bisogno di utilizzare l'ID in questo modo, utilizzare i parametri:

class Parent(object): 
    def __init__(self, id): 
     self.id = id 

class Child1(Parent): 
    _id_counter = count(0) 
    def __init__(self): 
     Parent.__init__(self, 100 + self._id_counter.next()) 
     print 'Child1:', self.id 

ecc

Questo presuppone che non sarà costruendo le istanze di Parent direttamente, ma che sembra ragionevole con il tuo codice di esempio.

Problemi correlati