本文介绍: 构造函数就是为了让我们实例对象的时候能够实现个性化定制

构造函数

        构造函数就是为了让我们实例对象的时候能够实现个性化定制

1. __init__()

        大家可以理解为在实例对象之前就会自动执行函数,如:

class A():   #定义类A
    def __init__(self,x,y): #创建构造方法__init__()
      #等号左边是绑定实例对象里面属性值,等号右边是传进来的参数
        self.x = x
        self.y = y
    def add(self):          #返回x,y的和
        return self.x + self.y
    
    def mul(self):          #返回x,y的积
        return self.x * self.y 

a = A(2,3)
a.add()
# 5
a.mul()
# 6
a.__dict__ #查看实例对象a中的数据
# {'x': 2, 'y': 3}
b = A(4,5)
b.add()
# 9
b.mul()
# 20
b.__dict__ #查看实例对象b中的数据
# {'x': 4, 'y': 5}

        上述代码中,我们没有调用__init__()方法,然而我们却得到了传进来的值,说明在我们调用方法之前就已经运行__init__()方法了。

2. 重写

        有构造函数的类的继承:

class A():   #定义类A
    def __init__(self,x,y): #创建构造方法__init__()
      #等号左边是绑定实例化对象里面属性值,等号右边是传进来的参数
        self.x = x
        self.y = y
    def add(self):          #返回x,y的和
        return self.x + self.y
    
    def mul(self):          #返回x,y的积
        return self.x * self.y 



class B(A):   #定义类B,并且继承类A
    def __init__(self,x,y,z):
        A.__init__(self,x,y) #继承父类方法
        self.z = z
    def add(self):
        return A.add(self) + self.z
    
    def mul(self):
        return A.add(self) * self.z

b = B(1,2,3)
b.add()
# 6
b.mul()
# 9

        通过上述代码可以看出我们直接通过 父类类名.方法名 重新父类的方法是可以达到效果的,不过这种方法会导致钻石继承。

3. 钻石继承

        所谓钻石继承是指,两个类同时继承了一个父类,并且这两个类又同时被一个子类继承。

下图,B1、B2 同时继承类A,而B1、B2 又同时被被C继承。

        可是钻石继承会导致什么后果呢,我们举个例子

class Grandmother:    #定义Grandmother类
    def __init__(self):
        print("我是奶奶,我进动物园了,我要买票!")

class Father(Grandmother):  #定义Father类,并且继承类Grandmother
    def __init__(self):
        Grandmother.__init__(self)
        print("我是爸爸,我进动物园了,我要买票!")

class Uncle(Grandmother):  #定义Uncle类,并且继承类Grandmother
    def __init__(self):
        Grandmother.__init__(self)
        print("我是叔叔,我进动物园了,我要买票!")

class Me(Father,Uncle): #定义Me类,并且继承类Father和Uncle
    def __init__(self):
        Father.__init__(self)
        Uncle.__init__(self)
        print("我是小明,我进动物园了,我要买票!")

m = Me()

 运行结果

我是奶奶,我进动物园了,我要买票!
我是爸爸,我进动物园了,我要买票!
我是奶奶,我进动物园了,我要买票!
我是叔叔,我进动物园了,我要买票!
我是小明,我进动物园了,我要买票!

         因为Father和Uncle同时继承了Grandmother类,导致Grandmother类中的__init__()在整个程序中被访问两次,对于变成来说变得不严谨了,就相当于因为奶奶同时使爸爸和叔叔的妈妈,所以奶奶要买两张票才能进动物园一样。

        有什么可以钻石继承的问题呢,这里就使用到super()函数

4. super()  

        super()可以在父类中搜索指定的方法,并自动绑定好self参数,避免重复调用的问题

class Grandmother:
    def __init__(self):
        print("我是奶奶,我进动物园了,我要买票!")

class Father(Grandmother):
    def __init__(self):
       super().__init__() #使用super函数
       print("我是爸爸,我进动物园了,我要买票!")

class Uncle(Grandmother):
    def __init__(self):
        super().__init__()   #使用super函数
        print("我是叔叔,我进动物园了,我要买票!")

class Me(Father,Uncle):
    def __init__(self):
       super().__init__()   #使用super函数
       print("我是小明,我进动物园了,我要买票!")

m = M()

运行结果

        这里奶奶只买了一次票,说明使用super可以避免重复调用的问题

我是奶奶,我进动物园了,我要买票!
我是叔叔,我进动物园了,我要买票!
我是爸爸,我进动物园了,我要买票!
我是小明,我进动物园了,我要买票!

5.MRO顺序

      prthon类是支持(多)继承的,一个类的方法和属性可能定义在当前类,也可能定义在基类针对这种情况,当调用类方法或类属性时,就需要当前类以及它的基类进行搜索,以确定方法或属性位置,而搜索顺序就称为方法解析顺序

        对于初学者来说,MRO顺序比较理解这里我们可以使用两种方法来查找MRO。

1. 通过mro()方法

Me.mro()

[<class ‘__main__.Me’&gt;, <class ‘__main__.Father’&gt;, <class ‘__main__.Uncle’>, <class ‘__main__.Grandmother’>, <classobject‘>]

        根据运行结果我们可以清晰地看出搜索顺序这里注意,对于<classobject’>,我们在上述代码中并没有定义,可是通过mro方法却能检测出来,这是因为object使所有类的基类,无论什么情况,都会自动调用的。

2. 通过mro属性 __mro__

Me.__mro__

(<class ‘__main__.Me’>, <class ‘__main__.Father’>, <class ‘__main__.Uncle’>, <class ‘__main__.Grandmother’>, <class ‘object’>)

原文地址:https://blog.csdn.net/qq_49873907/article/details/130115438

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任

如若转载,请注明出处:http://www.7code.cn/show_13883.html

如若内容造成侵权/违法违规/事实不符,请联系代码007邮箱suwngjj01@126.com进行投诉反馈,一经查实,立即删除

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注