简体   繁体   English

Python 类继承 __init__

[英]Python class inheritance __init__

So, here's the problem..所以,问题来了。。

if you do this:如果你这样做:

class x(object):
  def __init__(self):
    pass

why would you explicitly call init in child class to access parent class attribute?为什么要在子类中显式调用init来访问父类属性? (class y has class x attribute anyway.) (无论如何,y 类具有 x 类属性。)

class y(x):
  def __init__(self):
    x.__init__(self)

Cheers.干杯。

Edit:编辑:

I read this article https://linuxmeerkat.wordpress.com/2015/04/28/why-you-should-use-super-in-python/ , it says "In real life we tend to run the initializer for every parent class. This is simply because of how program designs tend to be . In our simple example a way to solve this is to explicitly call the initializer of A:" Could someone please explain?我读了这篇文章https://linuxmeerkat.wordpress.com/2015/04/28/why-you-should-use-super-in-python/ ,它说“在现实生活中,我们倾向于为每个父母运行初始化程序类。这仅仅是因为程序设计的方式。在我们的简单示例中,解决此问题的一种方法是显式调用 A 的初始化程序:“有人可以解释一下吗?

Because the child class inherits from the parent class, of course, that means everything: methods, attributes and the constructor.因为子类继承自父类,当然,这意味着一切:方法、属性和构造函数。 So instead of rewrite all the __init__ code, you just use what is already written in the parent class.因此,您无需重写所有__init__代码,而只需使用父类中已经编写的内容。 Hope it makes sense to you.希望它对你有意义。

The fact is that in python there is a clear distinction between class and instance attributes:事实是,在 python 中,类和实例属性之间有明显的区别:

  • Attributes declared in the class body, outside any method, are class attributes , they are the same for each object of that class and are the ones that are inherited by the subclasses.在任何方法之外的类主体中声明的属性类属性,它们对于该类的每个对象都是相同的,并且是由子类继承的属性 Be aware of the fact that doing instance_obj.class_att = something doesn't change the value of the class attribute, but simply creates an instance attribute and hides the shared class attribute for that object.请注意,执行instance_obj.class_att = something不会更改 class 属性的值,而只是创建一个实例属性并隐藏该对象的共享类属性。

  • Instance attributes are the ones that are declared with syntax instance_obj.att = something , they are not shared between instances and are the most similar thing to non-static attributes that you have in other programming languages and they are usually created in the init method.实例属性是使用语法instance_obj.att = something声明的属性,它们不在实例之间共享,并且与您在其他编程语言中拥有的非静态属性最相似,它们通常在init方法中创建。 self is just a convention to indicate the instance object automatically passed to methods. self只是一个约定,用于指示自动传递给方法的实例对象。

Here's an example:下面是一个例子:

class MyClass:
    c = 1                    #class attribute, the subclasses will inherit this
    def __init__(self):
        self.i = 1           #instance attribute

MyClass.c     #access attribute c of class MyClass
MyClass.i     #error! MyClass has no attribute i
x = MyClass() #calling __init__ creates instance attribute i for obj x
x.i           #access instance attribute i of object x
x.c           #access class attribute c of class MyClass
x.c = 2       #hide MyClass.c and create instance attribute c for obj x
x.c           #access instance attribute c of obj x

So, to sum up, doing:所以,总而言之,这样做:

class y(x):
    def __init__(self):
        x.__init__(self)

is useful because if the base class would have been something like this很有用,因为如果基类是这样的

class x:
    def __init__(self):
        self.i=1

you would have not been able to access the attribute i from any instances of y simply because they would not have it.您将无法从 y 的任何实例访问属性 i 仅仅因为它们没有它。

Instead of calling to the init function explicitly, you should use the super() method instead.与其显式调用init函数,不如使用 super() 方法。

In python 3.0+, you can jusy use:在 python 3.0+ 中,你可以随意使用:

class y(x):
    def __init__(self):
        super().__init__()

In python 2.7 or under, use:在 python 2.7 或更低版本中,使用:

class y(x):
    def __init__(self):
        super(self.__class__, self).__init__()

super() lets you avoid referring to the base class explicitly. super() 可让您避免显式引用基类。

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

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