Python 如何正确定义子类属性

Python 如何正确定义子类属性,python,class,attributes,subclass,Python,Class,Attributes,Subclass,我有一个人类和一个子类子类: 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__ == "__ma

我有一个
类和一个
子类
子类:

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'

为什么??如何解决此问题?

在打印
语句之前调用
setname

您应该明确调用

p.setname("name")
在访问它之前,请先设置“名称”

或者,如果不想设置name,则在父类中初始化name属性

    class Person:
        name = "your_name"
您必须“初始化”Person对象的属性。。我将使用<强> STR <强>方法打印对象,其类似于C++ <代码> STD:: 为什么?

您应该阅读异常消息:“AttributeError:SubPerson实例没有属性
'name'
”,这清楚地表明您使用表达式
p=SubPerson()在main中创建的
SubPerson
的实例
p
没有属性
'name'
-这就是它抛出
属性错误的原因

让我们在活动解释器上尝试您的代码,并查看:

>>> 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
从Person类继承的属性只有'display','setname',而不是
name

如何解决此问题?

您有以下几种技巧来更正代码:

  • Python是动态语言,您可以在对象命名空间中显式添加新名称,如下所示:

     >>> p.name = "grijesh"
     >>> p.__dict__            # Now `p` has 'name' attributes 
     {'name': 'grijesh'}
     >>> p.display()           # it is safe to call display
     Name: grijesh
    
  • 使用您的
    setname
    函数作为@Tasawer Nawaz的答案建议

  • 使用
    \uuuu init\uuuu
    函数并实现@T.C.答案中给出的对象构造函数


  • 基本上,在所有技术中,您都是在使用
    display(),父母和孩子都没有
    \uuuu init\uuuu
    -你期望发生什么?即使你让
    p
    成为一个人,这也不会起作用:这与子类化无关。我回答对了你的问题吗?使用class属性不是办法。改为使用实例属性。
    class SubPerson(Person):
     def __str__(self):
         return "Name: {0}".format(self.name)
    
    >>> 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.__dict__  
    {}                 # p don't have it any it own attribute 
    >>> dir(p)  # either don't inerited attribute 'name'
    ['__doc__', '__module__', 'display', 'setname']  
    >>> 
    
     >>> p.name = "grijesh"
     >>> p.__dict__            # Now `p` has 'name' attributes 
     {'name': 'grijesh'}
     >>> p.display()           # it is safe to call display
     Name: grijesh