简体   繁体   English

Python:从子类访问父属性

[英]Python: access a parent attribute from the child class

In Python, I have the following code that came up as a quiz question:在 Python 中,我有以下代码作为测验问题出现:

class Big_Cat:
    def __init__(self):
        self.x = "dangerous"

class Cat(Big_Cat):
    def __init__(self):
        self.y = "quiet"

new_cat = Cat()
print(new_cat.x, new_cat.y)

Since the cat class is inheriting from the BigCat class, it should also have access to variable x .由于 cat 类继承自BigCat类,因此它也应该可以访问变量x Then why is it throwing an error on the print screen line.那么为什么它会在打印屏幕行上抛出错误。 How else can new_cat get access the variable x from parent? new_cat如何才能从父级访问变量x

After inheriting from the super class, you must call the parent's __init__ (constructor).从超类继承后,必须调用父类的__init__ (构造函数)。 You can get a reference to the parent class by using super() .您可以使用super()获取对父类的引用。

Here is an example:下面是一个例子:

class Big_Cat:
    def __init__(self):
        self.x = "dangerous"

class Cat(Big_Cat):
    def __init__(self):
        super().__init__()
        self.y = "quiet"

new_cat = Cat()
print(new_cat.x, new_cat.y)

Output :输出

dangerous quiet

You can use super to call parent class' __init__您可以使用super来调用父类' __init__

In [1829]: class Big_Cat:
      ...:     def __init__(self):
      ...:         self.x = "dangerous"
      ...: 
      ...: class Cat(Big_Cat):
      ...:     def __init__(self):
      ...:         super(Cat, self).__init__()
      ...:         self.y = "quiet"
      ...: 
      ...: new_cat = Cat()

In [1830]: new_cat.x
Out[1830]: 'dangerous'

You need to call the constructor of the parent class inside the constructor of the child class in order for the child class to access the methods and attributes of the parent class.您需要在子类的构造函数中调用父类的构造函数,以便子类访问父类的方法和属性。 You can do so with the help of super() method.您可以在 super() 方法的帮助下做到这一点。

class Big_Cat:
    def __init__(self):
        self.x = "dangerous"

class Cat(Big_Cat):
    def __init__(self):
        super().__init__()
        self.y = "quiet"
        
new_cat = Cat()
print(new_cat.x, new_cat.y)

In Python there is a different approach than in true OOP languages as C++ or Java.在 Python 中,有一种与真正的 OOP 语言(如 C++ 或 Java)不同的方法。

There is no such thing as declaring an attribute in a direct way in a class definition so that this attribute will become automatically the instance's attribute:没有在类定义中以直接方式声明属性这样的事情,以便该属性将自动成为实例的属性:

class A:
    an_attribute = 0

The an_attribute is an attribute of the class A , but not an attribute of instances of this class: an_attributeA的属性,但不是此类实例的属性:

a = A()                     # an instance of the class A
print(a.an_attribute)       # 0 - so IS the an_attribute an instance's attribute?

It seems that an_attribute is the instance's attribute, but ...似乎an_attribute是实例的属性,但是......

A.an_attribute = 100        # changing the value of a CLASS attribute
print(a.an_attribute)       # 100; so it is NOT the independent OBJECT 's attribute

So how to create an object's attribute?那么如何创建对象的属性呢? Very easy:好简单:

a.an_attribute = 200        # creating an OBJECT's attribute

print(a.an_attribute)       # 200 — the OBJECT's attribute, independent of a CLASS' one
print(A.an_attribute)       # 100 — the CLASS attribute

From this moment the object a has its own attribute, different from the class attribute of the same name.从这一刻起,对象a就有了自己的属性,不同于同名的属性。

It means that different instances of the same class may have not only different values of the same attributes, but even totally different attributes:这意味着同一类的不同实例不仅可能具有相同属性的不同,甚至可能具有完全不同的属性:

b = A()
b.different_attribute = 500

Very weird situation:很奇怪的情况:

  • the object a has the attribute an_attribute , but the object b of the same class not,对象a具有属性an_attribute ,但同一类的对象b没有,
  • the object b has the attribute different_attribute , but the object a not.对象b具有属性different_attribute ,但对象a没有。

Is there a way to prescribe / initialize instances' attributes in a class definition?有没有办法在类定义中规定/初始化实例的属性?


Luckily, there is a special method __init__() , which runs automatically when you create an instance of a class, and which automatically receives just created object as its first parameter (commonly named as this ).幸运的是,有一个特殊的方法__init__() ,当你创建一个类的实例时它会自动运行,并且它会自动接收刚刚创建的对象作为它的第一个参数(通常命名为this )。

So you may assign to just created object an attribute by using this automatically filled parameter:因此,您可以使用此自动填充的参数为刚创建的对象分配一个属性:

class A:
    def __init__(self):
        self.an_attribute = 20
        self.different_attribute = 50

Now all new instances of the class A will have their own, object's attributes an_attribute and different_attribute (initialized with values 20 and 50 , respectively, which is not important here).现在,类A所有新实例都将拥有自己的对象属性an_attributedifferent_attribute (分别用值2050初始化,这里不重要)。


So, instance variables are not automatically inherited by a subclass.因此,子类不会自动继承实例变量 Other people already explained, how to go around it — not surprisingly in the __init__() method of a subclass with the help of the super() built-in function.其他人已经解释过,如何绕过它——在super()内置函数的帮助下,在子类的__init__()方法中并不奇怪。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM