2014-09-11 108 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实例对象。