Python继承:何时以及为什么__

2024-09-25 10:28:49 发布

您现在位置:Python中文网/ 问答频道 /正文

我是一个Python新手,试图理解继承方法背后的哲学/逻辑。问题最终涉及到为什么以及何时必须在子类中使用__init__方法。示例:

从超类继承的子类似乎不需要有自己的构造函数(__init__)方法。下面,狗继承哺乳动物的属性(名字、年龄)和方法(makenoise)。你甚至可以添加一个方法(do_a_trick),看起来一切都是“应该”的。在

但是,如果我想像在Cats类中那样在子类中添加一个新的属性,我会得到一个错误消息“self”没有被定义。但我在定义dog类时使用了“self”。区别的本质是什么? 我想用__init__(self,name)和{}来定义Cats。为什么有区别?在

class Mammals(object):

  def __init__(self,name):
    self.name = name
    print("I am a new-born "+ self.name)  
    self.age = 0

  def makenoise(self):
    print(self.name + " says Hello")

class Dogs(Mammals):

  def do_a_trick(self):
    print(self.name + " can roll over")

class Cats(Mammals):

 self.furry = "True"  #results in error `self' is not defined


mymammal = Mammals("zebra") #output "I am a new-born zebra"
mymammal.makenoise()  #output "zebra says hello"
print(mymmmal.age)    #output 0

mydog = Dogs("family pet") #output "I am a new-born family pet"
mydog.makenoise()  #output "family pet says hello"
print(mydog.age)  # output 0
mydog.do_a_trick() #output "family pet can roll over"

Tags: 方法nameselfoutputinit子类familydo
3条回答

Python类顶层的声明成为类属性。如果来自C++或java背景,这与声明静态成员变量类似。不能在该级别分配实例属性。在

变量self通常指的是类的一个特定实例,从中调用了方法。当使用语法inst.method()进行方法调用时,函数的第一个参数是调用该方法的对象inst。在您的例子中,通常按照约定,该参数在方法的函数体中命名为self。您可以将self看作是方法体中的一个有效标识符。您的赋值self.furry = True不在方法中发生,因此self没有在那里定义。在

你基本上有两个选择来实现你想要的。第一种方法是正确地将furry定义为cat类的属性:

class Cat(Mammals):
    furry = True

    # Rest of Cat implementation ...

也可以在cat构造函数中设置实例变量furry的值:

^{pr2}$

如果您正在接触Python,我强烈建议您阅读Python文档的以下两部分:

Python classes

Python data model special methods(更高级)

Explicit is better than implicit.

但是,您可以执行以下操作:

class Dogs(Mammals):
    def __init__(self):
        #add new attribute
        self.someattribute = 'value'
        Mammals.__init__(self)

或者

^{pr2}$

if I wanted to add a new attribute in the subclass as I attempt to do in the Cats class, I get an error saying "self" is not defined. Yet I used "self" in the definition of the dog class.

在你的超类哺乳动物中,有一个__init__函数,它接受你选择的一个参数来调用self。当您在__init__函数体中时,此参数在作用域内-它是与任何局部变量一样的局部变量,并且在其包含函数终止后无法引用它。 在Dog类上定义的函数do_a_trick,也接受一个名为self的参数,并且它也是该函数的本地函数。 这些变量的特殊之处并不是它们的名称(您可以随意调用它们),而是事实上,作为python中实例方法的第一个参数,它们获得了对调用它们的对象的引用作为它们的值。(把最后一句话再读几遍,这是理解这一点的关键,你可能第一次就不会明白了。)

现在,在Cat中,有一行代码根本不在函数中。此时,范围内没有任何内容,包括self,这就是它失败的原因。如果要在Cat中定义一个函数,该函数接受一个名为self的参数,则可以引用该参数。如果该参数碰巧是Cat上实例方法的第一个参数,那么它将具有调用它的Cat实例的值。否则,它就会有任何被传给它的东西。在

*你的选择很明智!在

相关问题 更多 >