简体   繁体   中英

Python: access a parent attribute from the child class

In Python, I have the following code that came up as a quiz question:

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 . Then why is it throwing an error on the print screen line. How else can new_cat get access the variable x from parent?

After inheriting from the super class, you must call the parent's __init__ (constructor). You can get a reference to the parent class by using 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__

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.

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.

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:

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 ...

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.

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,
  • the object b has the attribute different_attribute , but the object a not.

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 ).

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).


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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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