2013-11-01 30 views
7

Aşağıda, base_id ve _id bir sınıf değişkeni olup, tüm alt sınıflar arasında paylaşılır.
Onları her bir sınıfa ayırmanın bir yolu var mı? Söz konusu söylediği gibipython'da sınıf değişkenini geçersiz kılar mı?

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

Yüzlerce hane sınıfını temsil etmenin neden özel bir sebebi var? 100'den fazla örneğe sahip olursanız ne olur? Öyleyse üst üste geleceksin. Kimliği nerede göreceksiniz ve sınıfları birbirinden ayırmak için ID'yi kullanmanın daha iyi bir yolu olabilir mi? (Belki de bazı ekstra bilgileri görüntüleyebilirsiniz.) – jpmc26

+1

Bu aslında önemli değil; eugene ID'leri 2-tuple değiştirmiş olsa bile (örn. (Child) 1 için (1,0), (1,1), (1,2) ...) bağımsız sayaç oluşturma problemi kalır. –

cevap

3

, metaclasses kullanmanız gerekir. Bir şey yazmayı düşünüyordum, ama there's already a good long description of metaclasses on SO, o yüzden kontrol et. Alt sınıf oluşturma, kısaca, alt sınıf oluşturmayı denetlemenize izin verir.

Temel olarak, yapmanız gereken, Parent alt sınıfının oluşturulması üzerine, _id üyesini yeni oluşturulan alt sınıfa ekleyin.

2

, _id ebeveyn ve tüm çocukların sınıflarına tarafından paylaşılır. Her çocuk sınıfı için _id tanımlayın.

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 

GÜNCELLEME

kullanma metaclass: Eğer falsetru anlaşılacağı gibi KURU ilkesini ihlal etmek istemiyorsanız

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

gerçekten kimliğini bu şekilde kullanmanız gerekiyorsa, kullanın parametreleri:

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 

vb Bu doğrudan Parent örneklerini inşa olmayacak varsayar

ama o makul görünüyor senin örnek kod

İlgili konular