2014-09-11 107 views
2

我有一個Person類和SubPerson子類:如何正確定義一個子類屬性

class Person: 

    def setname(self, name): 
     self.name = name 

    def display(self): 
     print(self.name) 


class SubPerson(Person): 
    def display(self): 
     print("Name: {0}".format(self.name)) 


if __name__ == "__main__": 
    p = SubPerson() 
    p.display() 

但是當我打電話的p顯示方法,我有以下錯誤:

File "./person.py", line 14, in display 
    print("Name: {0}".format(self.name)) 
AttributeError: SubPerson instance has no attribute 'name' 

爲什麼?我怎樣才能解決這個問題?

+4

你永遠不會調用'setname',父母和孩子都不會有'__init__' - 你期望發生什麼? – jonrsharpe 2014-09-11 12:20:03

+1

即使你使'p'成爲Person,它也不起作用:它與子類化無關。 – 2014-09-11 12:34:23

+0

我是否正確回答了您的問題? – Oni1 2014-09-11 13:18:09

回答

4
class Person: 
def __init__(self, name=""): 
    self.name=name 

#def setname(self, name): 
# self.name = name 

#instead of display 
def __str__(self): 
    return self.name 

#def display(self): 
# print(self.name) 

if __name__=='__main__': 
    p=Person("YourName") 
    print p 

你必須「初始化」你對你的Person對象的屬性..我將實現STR方法來打印你的對象及其在C++ std::operator<<如..

而子類是這樣的:

class SubPerson(Person): 
def __str__(self): 
    return "Name: {0}".format(self.name) 

還有一些其他的方法(len個得到,等..),你可以改寫你自己的類..

0

致電setname就是您的print聲明。

0

你明確應該訪問它

1

請設置 「名稱」 第一

p.setname("your_name") 

,或者如果你不想設置名稱,然後初始化父name屬性之前調用

p.setname("name") 

class Person: 
     name = "your_name" 
+3

使用類屬性不是要走的路。改用實例屬性。 – Matthias 2014-09-11 12:38:40

1

Why?

你應該閱讀異常消息:「AttributeError的:SubPerson實例沒有屬性'name'」,這清楚地表明,你已經在使用的主要表達p = SubPerson()創建SubPerson的實例p沒有屬性'name' - 這就是爲什麼它會拋出AttributeError異常。

讓我們試着主動解釋你的代碼,看看:

>>> class Person: 
... def setname(self, name): 
... self.name = name 
... def display(self): 
... print(self.name) 
... 
>>> class SubPerson(Person): 
... def display(self): 
... print("Name: {0}".format(self.name)) 
... 
>>> p = SubPerson() 
>>> p.name # Notice 
Traceback (most recent call last): 
    File "<stdin>", line 1, in <module> 
AttributeError: SubPerson instance has no attribute 'name' 
>>> 

通知行p.name - 你得到相同的異常!事實上p有名稱的屬性'name'可以用內省技術使用__dict__和繼承使用dir()功能屬性的p所有屬性列表,請參閱下面

>>> p.__dict__ 
{}     # p don't have it any it own attribute 
>>> dir(p) # either don't inerited attribute 'name' 
['__doc__', '__module__', 'display', 'setname'] 
>>> 

通知只是屬性,從Person類p繼承是「顯示器','setname'但不是name

How can I fix this?

你有一些技巧來糾正如下代碼:

  1. Python是動態語言,你可以明確地在對象名稱空間添加新的名稱:

    >>> p.name = "grijesh" 
    >>> p.__dict__   # Now `p` has 'name' attributes 
    {'name': 'grijesh'} 
    >>> p.display()   # it is safe to call display 
    Name: grijesh 
    
  2. 使用您的setname作爲@Tasawer Nawaz的回答建議。

  3. 使用__init__函數和實現對象的構造函數作爲@ T.C.的答案給出。

基本上在所有技術要連接'name'屬性在display()函數法訪問它之前SubPerson實例對象。