super () method Detailed

super () method Detailed

A process of calling the parent class alone

Requirements: write a class, and then write a subclass inherit, the methods used to call the parent class subclass 1.
Use 1 Print: fat boss, to wrap betel nut.

Then the first to write a fat boss of the parent class, execute the following:

class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('FatFather的name是%s' % self.name)
        print('FatFather的init调用结束')


def main():
    ff = FatFather("胖子老板的父亲")

Run this constructor fat boss superclass __init__ follows:

if __name__ == "__main__":
    main()
FatFather的init开始被调用
FatFather的name是胖子老板的父亲
FatFather的init调用结束

Well, here to write a subclass, that is, fat boss class, inheriting class above

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')


# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        FatFather.__init__(self, name)  # 直接调用父类的构造方法
        print("%s 的爱好是 %s" % (name, self.hobby))


def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")

In this above code, I use FatFather .__ init __ (self, name ) method of the parent class called directly.

Results are as follows:

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主

Two, super () basic concepts

In addition to the direct method using FatFather .__ init __ (self, name), you can also use super () method is invoked.

You first need to look super () method description and syntax of understanding about the use of super () method.

2.1 Description

super()The method is a function call the parent class (superclass) is used. super is used to solve the problem of multiple inheritance, class name with no problem call the parent class method directly when using single inheritance, but if you use multiple inheritance, involves the search order (MRO), repeated calls (diamond inheritance) and various other problem.

MRO is the way class resolution order table, in fact, is the inheritance order table when the parent class method.

2.2 Syntax

The following is the syntax super () method:

super(type[, object-or-type])

parameter

type - class

object-or-type - based, generally self

And a difference Python3.x Python2.x are: Python 3 can be used directly super () xxx instead of super (Class, self) .xxx.:

Python3.x example:

class A:
    pass
class B(A):
    def add(self, x):
        super().add(x)

Python2.x example:

class A(object):   # Python2.x 记得继承 object
    pass
class B(A):
    def add(self, x):
        super(B, self).add(x)

2.3 single inheritance using super ()

Use super () method to rewrite the fat boss just inherit the parent class init constructor

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')


# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))


def main():
    #ff = FatFather("胖子老板的父亲")
    fatboss = FatBoss("胖子老板", "打斗地主")

When using the super method from above, because it is a single inheritance, it can be directly used.

Run as follows:

if __name__ == "__main__":
    main()
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主

So why single inheritance can be used directly it? Because the super () method if multiple inheritance, it will involve a MRO ( order table when inherited from the parent class method ) call scheduling problem.

Here you can print it and see single inheritance MRO order (FatBoss .__ mro__).

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name):
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')


# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby):
        print('胖子老板的类被调用啦!')
        self.hobby = hobby
        #FatFather.__init__(self,name)   # 直接调用父类的构造方法
        super().__init__(name)
        print("%s 的爱好是 %s" % (name, self.hobby))


def main():

    print("打印FatBoss类的MRO")
    print(FatBoss.__mro__)

    print()
    print("=========== 下面按照 MRO 顺序执行super方法 =============")
    fatboss = FatBoss("胖子老板", "打斗地主")

The above code uses FatBoss .__ mro__ calling sequence can be printed out after the inheritance class C3 FatBoss python parser through calculation algorithm.

Run as follows:

if __name__ == "__main__":
    main()
打印FatBoss类的MRO
(<class '__main__.FatBoss'>, <class '__main__.FatFather'>, <class 'object'>)

=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的类被调用啦!
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束
胖子老板 的爱好是 打斗地主

(<Class 'from the above results main .FatBoss'>, <class ' main .FatFather'>, <class 'Object'>) can be seen, super () method will be called directly from a parent class FatBoss FatFather, so a single Inheritance is not the problem.
So if multiple inheritance, then what is the problem?

More than 2.4 inheritance using super ()

Suppose to write her class a fat boss, the boss's wife and fat class, this time his daughter need to inherit two classes (class fat boss, the boss wife fat class).
Because fat boss has a hobby, fat boss's wife needs to work to do the housework, taking into account that her daughter needed help.
At this time, her daughter inherits is the need to use both methods of the parent class, then how to write it?
Let's look at the implementation code:

# 胖子老板的父类
class FatFather(object):
    def __init__(self, name, *args, **kwargs):
        print()
        print("=============== 开始调用 FatFather  ==================")
        print('FatFather的init开始被调用')
        self.name = name
        print('调用FatFather类的name是%s' % self.name)
        print('FatFather的init调用结束')
        print()
        print("=============== 结束调用 FatFather  ==================")


# 胖子老板类 继承 FatFather 类
class FatBoss(FatFather):
    def __init__(self, name, hobby, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBoss  ==================")
        print('胖子老板的类被调用啦!')
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 的爱好是 %s" % (name, hobby))
        print()
        print("=============== 结束调用 FatBoss  =================")


# 胖子老板的老婆类 继承 FatFather类
class FatBossWife(FatFather):
    def __init__(self, name, housework, *args, **kwargs):
        print()
        print("=============== 开始调用 FatBossWife  ===============")
        print('胖子老板的老婆类被调用啦!要学会干家务')
        #super().__init__(name)
        ## 因为多继承传递的参数不一致,所以使用不定参数
        super().__init__(name, *args, **kwargs)
        print("%s 需要干的家务是 %s" % (name, housework))
        print()
        print("=============== 结束调用 FatBossWife  ==============")


# 胖子老板的女儿类 继承 FatBoss FatBossWife类
class FatBossGril(FatBoss, FatBossWife):
    def __init__(self, name, hobby, housework):
        print('胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主')
        super().__init__(name, hobby, housework)


def main():

    print("打印FatBossGril类的MRO")
    print(FatBossGril.__mro__)

    print()
    print("=========== 下面按照 MRO 顺序执行super方法 ===========")
    gril = FatBossGril("胖子老板", "打斗地主", "拖地")

Results are as follows:

if __name__ == "__main__":
    main()
打印FatBossGril类的MRO
(<class '__main__.FatBossGril'>, <class '__main__.FatBoss'>, 
<class '__main__.FatBossWife'>, <class '__main__.FatFather'>, <class 'object'>)

=========== 下面按照 MRO 顺序执行super方法 =============
胖子老板的女儿类被调用啦!要学会干家务,还要会帮胖子老板斗地主

=============== 开始调用 FatBoss  ======================
胖子老板的类被调用啦!

=============== 开始调用 FatBossWife  ==================
胖子老板的老婆类被调用啦!要学会干家务

=============== 开始调用 FatFather  ====================
FatFather的init开始被调用
调用FatFather类的name是胖子老板
FatFather的init调用结束

=============== 结束调用 FatFather  ===================
胖子老板 需要干的家务是 拖地

=============== 结束调用 FatBossWife  =================
胖子老板 的爱好是 打斗地主

=============== 结束调用 FatBoss  ======================

Operating results from the above point of view, I deliberately call to begin and end each class are printing logo can be seen. Each call class is started according to the start MRO order, one by one and then ends. Then there is the need to inherit because of different parent class, not necessarily parameters. Therefore, all of the parent class should be preceded by the indefinite parameters * args, ** kwargs, otherwise parameters will not correspond to the error.

Third, pay attention

  • super () .__ init__ with respect to the class name .__ init__, in succession on a single use substantially no difference
  • But there are differences in the multiple inheritance, super method to ensure that each parent class's method only once, and the class name of the method causes method is executed multiple times, you can try to write code output view
  • When multiple inheritance, use the super method of transmission parameters parent class, the reason should be because the python algorithm resulting in super, all the parameters must be passed, otherwise it will error
  • When single inheritance, the use of super method, you can not transfer all, you can only pass the required parameters parent class method, otherwise it will error
  • When multiple inheritance, with respect to the class name .__ init__ method, each parent should all write again, and use the super method, just write a word they all perform the method of the parent class, which is why all the required multiple inheritance one reason for parameter passing

Fourth, practice

What is the output of the following code will be? Speak your answers and explanations.

class Parent(object):
    x = 1


class Child1(Parent):
    pass


class Child2(Parent):
    pass


print(Parent.x, Child1.x, Child2.x)
1 1 1
Child1.x = 2
print(Parent.x, Child1.x, Child2.x)
1 2 1
  • Note: Child1 already have their own x
Parent.x = 3
print(Parent.x, Child1.x, Child2.x)
3 2 3

Guess you like

Origin www.cnblogs.com/Dr-wei/p/11847926.html