Python

2012-11-15 37 views
31

Inherited sınıf değişken modifikasyonu Bir alt sınıfın, üst öğesinden devraldığı bir sınıf değişkenini değiştirmek istiyorum.Python

Ben çizgisinde bir şey yapmak istiyorum:

Child.foobar = ["hello", "world"] 

yapabileceğim:

class Child(Parent): 
    def __init__(self): 
     type(self).foobar.extend(["world"]) 

ama sonra her zaman örneğini ideal

class Parent(object): 
    foobar = ["hello"] 

class Child(Parent): 
    # This does not work 
    foobar = foobar.extend(["world"]) 

ve var Çocuk’un bir örneği, “dünya” listeye eklenir, bu da istenmeyen bir durumdur. Ben daha da değiştirebilir:

class Child(Parent): 
    def __init__(self): 
     if type(self).foobar.count("world") < 1: 
      type(self).foobar.extend(["world"]) 

ama işe yarıyor önce Çocuk bir örneğini gerekir çünkü bu hala kesmek.

Daha iyi bir yolu var mı?

cevap

35

, ebeveyn sınıfının listesini değiştiremezsiniz:

class Child(Parent): 
    foobar = Parent.foobar + ['world'] 

Bunun, mirastan bağımsız olarak çalıştığını unutmayın; bu muhtemelen iyi bir şeydir.

+1

Bu fevkalade parlak ve basit! Ayrıca, çocuğun özniteliğinin başlangıç ​​değerinin ebeveynin özniteliği ile aynı olması gerekiyorsa, kopya ithal derin bilgisinden yararlanmanın yararı olacaktır; foobar = deepcopy (Parent.foobar) – zen11625

16

Sınıf değişkenlerinizde değişebilir değerler kullanmamalısınız. __init__() örneği başlatıcısı kullanılarak yerine örneği böyle değerler ayarlayın:

class Parent(object): 
    def __init__(self): 
     self.foobar = ['Hello'] 

class Child(Parent): 
    def __init__(self): 
     super(Child, self).__init__() 
     self.foobar.append('world') 

Aksi neyi foobar liste ama alt sınıfları ile de, sadece örnekleri arasında paylaşılan bu olur.

Her halükarda, durumları değişebilen bir sınıf değişkeniyle paylaşmak istemesine rağmen, üst sınıfların mutables'lerini değiştirmek zorunda kalmazsınız;

class Parent(object): 
    foobar = ['Hello'] 

class Child(Parent): 
    foobar = Parent.foobar + ['world'] 

bir yenifoobar değişken Child sınıf için oluşturulan: bir isme sadece atama yeni bir değişken yaratacak. Ödev kullanarak yeni bir liste örneği oluşturdunuz ve Parent.foobar mutable etkilenmiyor.

Bu gibi durumlarda iç içe geçmiş malzemelere dikkat edin; Gerekirse derin kopyalar oluşturmak için copy modülünü kullanın. (Sadece bir yerde değiştirebilir veya oraya beklenen değerleri koyabilirsiniz beri başlamak için anlamsız görünüyor) Eğer alt sınıfta ayrı bir liste yapmak istiyorum varsayarsak