2015-01-28 16 views
5

Python'da yeniyim ve yaptığımın doğru olduğundan emin değildim. Bir temel sınıf A ve bir kalıtım sınıfı B var. Bunu çalıştırdığınızdaPython özelliği devralma

class A(object): 

    def __init__(self, name): 
     self.__name = name 

    @property 
    def name(self): 
     return self.__name 

    @name.setter 
    def name(self, name): 
     self.__name = name 

class B(A): 
    def __init__(self, name): 
     super(NominalValue, self).__init__(name) 

    @property 
    def name2(self): 
     return self.__name2 

    @name2.setter 
    def name2(self, n): 
     self.__name2 = n 

    def toString(): 
     print self.__name + self.__name2 

if __name__ == "__main__": 
    instance = B('name'); 
    instance.toString() 

o sınıf B herhangi bir nitelik __name yok şikayet ediyor.

AttributeError: 'B' object has no attribute '_B__name' 

Açıkçası doğru bir şekilde miras yapıyorum. Özelliklerin doğru şekilde miras alınmasını nasıl sağlarız ve miras alınan sınıftaki özniteliklerin tekrarlanmasını önler misiniz?

+3

Çift baştaki alt çizgi, kalıtımınızı engelleyen [özel anlam] (https://docs.python.org/2/tutorial/classes.html#private-variables-and-class-local-references) içeriyor. Üst sınıfın '__name' özniteliğine erişmek için bence 'self._A__name' olarak adlandırmanız gerekir. –

+2

Cevabında 6502'den bahsedildiği için, sınıfınıza bir özellik yazmak zorunda kalmadan * PLANLAMA * olması gerekmemelidir.Bu, Python'daki özelliklerin güçlü yönlerinden biridir: bir özelliği bir mülkiyete anında dönüştürmek çok kolaydır. Bir özelliği almak, ayarlamak veya silmek için özel bir mantığa sahip olmanız gerektiği kanıtlanmadıkça, bunu yapmak için bir özellik kullanmayın. –

cevap

7

__name gibi iki alt çizgi ile başlayan öznitelikler özel değişkenler olarak belirtilir. Bunlara ilişkin gerçek bir KORUMA yoktur (başka bir deyişle, eğer bulabilirseniz, ona erişebilirsiniz), ancak erişilmesi daha az kolay olacak şekilde isimlendirilmişlerdir. More information about that can be found on the docs page

şeklinde __spam herhangi tanımlayıcı (en az iki gelen alt çizgi, en fazla bir arka alt çizgi ile) tokuş classname soyulmuş lider çizgi (ler) mevcut sınıf adı _classname__spam, ile ikame edilir. Bu nedenle

, hatta A 's __name niteliğini devralmasını olsa türe B herhangi nesnede bir öznitelik __name yok. Sahip olduğunuz _A__name özniteliğidir. Yani nasıl ad-bozma çalışır: Bu halk olması gerekiyordu olmadığını gelecekteki kullanıcılara sadece bir bayrak olan yerine _name kullanabilirsiniz _classname__attributename

__attributename olur. O zaman bütün kodunuz çalışmalı.

5

Çift alt çizgi ile öntanımlı öznitelik adları özellikle derleyici tarafından ele alınır ve Python'u daha iyi anlayana kadar bunları engellemelisiniz.

Çoğu Python programcısı neden özel olduklarını bilmezler ve yine de mutlu ve verimli bir programlama hayatı yaşayabilirler. Onlar da nesnel olarak çirkinler ... sence de öyle değil mi?

Ayrıca, Python'da sadece eğlenmek için getter ve ayarlayıcı kullanmaya başlamadığınızı unutmayın. Sadece bir veri üyesi ile başlayın ve sadece (ve sadece) gerekli olduğunda özelliklerine geçin. Basitçe üye döndüren ve basitçe değiştiren bir ayarlayıcı için bir kodlayıcı kod yazmak anlamsızdır. Üye erişiminde özel işlem yapmanız gerektiğinde (ve eğer), bunları özelliklerde değiştirdiğinizde, kodunuzu sınıfınızı kullanarak değiştirmeniz gerekmez.

Teknik açıklama tarafında Python, diğer sınıflardaki aynı adlandırılmış özniteliklere sahip istenmeyen çakışmaları önlemek için yalnızca çift alt çizgi ile başlayan özniteliklere sınıf adını ekler. Ancak bu tür bir problem çok yaygın değildir ve bu yüzden Python programcılarının çoğu bu özelliğin gerekliliğine sahip olmamıştır.