2016-11-17 64 views
0

我最近開始學習python,並且我很難在python中如何繼承。python中的繼承,屬性錯誤

我創建了兩個類,一個名爲Animal,另一個名爲Dog。 Dog類繼承Animal類。我在動物類中有一些屬性,如名稱,高度,聲音等,我想在Dog類中使用。我使用init動物類的方法設置屬性。

class Animal: 
    __name = "" 
    __height = 0 
    __weight = 0 
    __sound = 0 

    def __init__(self, name, height, weight, sound): 
     self.__name = name 
     self.__height = height 
     self.__wight = weight 
     self.__sound = sound 

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

    def get_name(self): 
     return self.__name 

    def set_height(self, height): 
     self.__height = height 

    def get_height(self): 
     return self.__height 

    def set_weight(self, weight): 
     self.__weight = weight 

    def get_weight(self): 
     return self.__weight 

    def set_sound(self, sound): 
     self.__sound = sound 

    def get_sound(self): 
     return self.__sound 

    def get_type(self): 
     print("Animal") 

    def tostring(self): 
     return "{} is {} cm tall and {} kilograms and says {}".format(self.__name, 
                     self.__height, 
                     self.__weight, 
                     self.__sound) 


cat = Animal("whiskers", 50, 20, "meow") 
print(cat.tostring()) 


class Dog(Animal): 
    __owner = None 

    def __init__(self, name, height, weight, sound, owner): 
     super(Dog, self).__init__(name, height, weight, sound) 
     self.__owner = owner 

    def set_owner(self, owner): 
     self.__owner = owner 

    def get_owner(self): 
     return self.__owner 

    def get_type(self): 
     print("dog") 

    def tostring(self): 
     return '{} is {} cm tall and {} kilograms and says {} His owner is {}'.format(self.__name, 
                         self.__height, 
                         self.__weight, 
                         self.__sound, 
                         self.__owner) 

    def multiple_sounds(self, how_many=None): 
     if how_many is None: 
      print(self.get_sound()) 
     else: 
      print(self.get_sound() * how_many) 
my_dog = Dog("spot", 50, 40, "Ruff", "Derek") 
print(my_dog.tostring()) 

問題是當我嘗試打印使用Dog類的對象的所有屬性,會顯示一個錯誤,說「

*line 73, in tostring 
    return '{} is {} cm tall and {} kilograms and says {} His owner is {}'.format(self.__name, 
AttributeError: 'Dog' object has no attribute '_Dog__name'* 

誰能幫我看看這個問題在這個代碼?

回答

2

以雙下劃線開頭的成員是私有類型,所以它們不能從cild類訪問,你應該使用單下劃線Python不使用像C++或java這樣的隱式訪問說明符,而是使用特殊的名稱約定:名稱爲_前綴用於保護,__的名稱爲私有。此外python不檢查你是否違反了這個約定,在類之外訪問受保護的或私有的方法被認爲是一種不好的做法。如果你用雙下劃線開始一個名字,它會以一種特殊的方式被破壞。所以__name實際上變成了_Animal__name當你在Animal類和_Dog__name當你在Dog中使用它。

+0

問題通過將雙下劃線更改爲單下劃線解決。謝謝您的幫助 ! – Yousaf

1

問題是你的名字中有雙下劃線前綴。他們觸發了名稱混亂。

你應該避免使用這些。他們沒有做你期望的。

1

在Python中使用雙下劃線使變量「私有」。它類似於在其他語言中使用private關鍵字。如果要訪問父類之外的屬性,則需要刪除它們。

Python documentation touches on this subject

由於存在一個有效的用例爲類私有成員(即,以避免名稱的名稱衝突與由子類定義名稱),存在對這樣的機制支持有限,所謂的名字mangling。 __spam(至少包含兩個前導下劃線,最多一個尾部下劃線)的任何標識符都被_classname__spam文本替換,其中classname是當前類名,前導下劃線已被刪除。只要它在類的定義內發生,就不會考慮標識符的語法位置。 (強調我的)