Python 多继承中的一个诡异现象 既是 Father又是grandfather

 更新时间:2021年09月18日 11:01:17   作者:itskingname  
我们知道,在面向对象编程里面,继承是一个很重要的概念。子类可以使用父类的方法和属性,接下来小编将用举例的方式为大家讲解Python 多继承中的一个诡异现象 其即是爸爸又是爷爷的奇葩现象,感兴趣的小伙伴可以看下面文章具体了解

我们知道,在面向对象编程里面, 继承 是一个很重要的概念。子类可以使用父类的方法和属性。

例如下面这段代码:

class Father:
    def __init__(self):
        self.address = '上海'

    def say(self):
        print('我是爸爸')

class Son(Father):
    def __init__(self):
        super().__init__()

    def say(self):
        print('我是儿子')

son = Son()
print(son.address)

运行效果如下图所示:

从图中可以看到,子类并没有 self.address 这个属性,但是当我们直接打印的时候,并不会报错,它会自动使用父类的 address 属性。

显然,如果一个属性,子类也没有,父类也没有,那肯定会报错,如下图所示:

我们也知道,Python 是支持多继承的,一个子类可以有多个父类。那么,大家请看下面这段代码:

class GrandFather:
    def __init__(self):
        self.address = '上海'

    def say(self):
        print('我是爸爸')

class Father:
    def __init__(self):
        self.age = 100
    
    def where(self):
        print('我现在住在:', self.address)

class Son(GrandFather, Father):
    def __init__(self):
        super().__init__()

    def say(self):
        print('我是儿子')

son = Son()
son.where()

运行效果如下图所示:

大家仔细观察,会发现这段代码有点奇怪。我调用的是 son.where() 方法,由于 Son 类没有这个方法,于是它会去它的两个父类里面找。于是在 Father 这个父类里面找到了。于是执行 Father 里面的 where() 方法,目前为止没有问题。

但接下来就不对了, .where() 方法里面,调用了 self.address 属性。可问题是 Father 这个类它并没有 .address 属性啊!而且 Father 也没有父类,那么这个 .address 属性是从哪里来的?

难道说,在开发者不知道的隐秘的角落里面, GrandFather 类悄悄成为了 Father 的父类?这样一来, GrandFather 岂不是又是 C 的父类,又是 C 的父类的父类? GrandFather 既是爸爸又是爷爷?

实际上,并不存在这么混乱的关系。要解释这个现象,我们就要从 self 这个东西说起。

我们知道,类的属性都是以 self 开头,方法的第一个参数也是 self 。那么这个  self 到底是什么东西?我们用一段小代码来看看它是什么东西:

class A:
    def get_self(self):
        return self

test = A()
what_is_self = test.get_self()

test is what_is_self

运行效果如下图所示:

从图里面可以看到, self 实际上就是这个类的实例。我们再来看有继承的情况:

class A:
    def get_self(self):
        return self

class B(A):
    def __init__(self):
        ...

test = B()
what_is_self = test.get_self()

print(what_is_self)

从图中可以看到,虽然我在 A 类的 .get_self() 方法中返回了 self ,但这个 self 实际上是 B 类的实例。因为我自始至终就只初始化了 B 类,并没有初始化 A 类。A 虽然是 B 类的父类。但父类的  self 都会变成子类的实例。

明白这一点以后,前面的问题就很好解释了,我们多打印一些信息:

大家注意画红线的地方, self 始终都是 Son 类的实例。所以,一开始初始化 .address 的时候,就是初始化的 Son 的实例的 .address 属性。后面在 .where 里面调用 .address 的时候,也是读取的 Son 的实例的 .address 属性。所以,并不存在 Father 类去读 GrandFather 类的情况。自始至终,都是 Son 类的实例在进行各种操作。

所以,在这个例子里面,当使用了继承以后,所有父类的属性和方法,子类如果有相同的名字,那么以子类的为准。如果子类没有定义,那么父类的属性和方法,其实都会跑到子类里面去。 所有看起来是父类进行的操作,其实都是子类在进行 。上面的代码,甚至可以近似等价于:

由于 say 方法在子类中有了定义,所以子类覆盖父类。以子类的 say 方法为准。 where address 由于子类没有定义,所以 Father 类的 where 方法和 GrandFather 里面的 address 属性,都会直接 跑 到子类里面。

到此这篇关于Python 多继承中的一个诡异现象 既是 Father又是grandfather的文章就介绍到这了,更多相关Python 多继承中的一个诡异现象 内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • PyTorch变分自编码器的构建与应用小结

    PyTorch变分自编码器的构建与应用小结

    变分自编码器是一种强大的深度学习模型,用于学习数据的潜在表示并能生成新的数据点,使用PyTorch实现VAE不仅可以加深对生成模型的理解,还可以利用其灵活性进行各种实验,这篇文章主要介绍了PyTorch变分自编码器的构建与应用,需要的朋友可以参考下
    2024-07-07
  • python里的单引号和双引号的有什么作用

    python里的单引号和双引号的有什么作用

    在本篇文章里小编给大家分享的是一篇关于python里的单引号和双引号的作用的相关内容,需要的朋友们可以学习下。
    2020-06-06
  • 利用python绘制CDF图的示例代码

    利用python绘制CDF图的示例代码

    这篇文章主要为大家详细介绍了如何利用python实现绘制CDF图,文中的示例代码简洁易懂,具有一定的借鉴价值,感兴趣的小伙伴可以学习一下
    2023-08-08
  • Python制作进度条的几种方法

    Python制作进度条的几种方法

    如果你之前没用过进度条,八成是觉得它会增加不必要的复杂性或者很难维护,其实不然。要加一个进度条其实只需要几行代码,快跟随小编一起学习学习吧
    2022-12-12
  • Linux添加Python path方法及修改环境变量的三种方法

    Linux添加Python path方法及修改环境变量的三种方法

    这篇文章主要介绍了Linux添加Python path方法及修改环境变量的三种方法,Linux 下设置环境变量有三种方法,一种用于当前终端,一种用于当前用户,一种用于所有用户,本文对每种方法给大家介绍的非常详细,需要的朋友可以参考下
    2022-07-07
  • Python高斯消除矩阵

    Python高斯消除矩阵

    今天小编就为大家分享一篇关于Python高斯消除矩阵,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要的朋友一起跟随小编来看看吧
    2019-01-01
  • Python列表中多元素删除(移除)的实现

    Python列表中多元素删除(移除)的实现

    本文主要介绍了Python列表中多元素删除(移除)的实现,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2023-03-03
  • pandas读取中文xlsx文件出现的问题

    pandas读取中文xlsx文件出现的问题

    这篇文章主要介绍了pandas读取中文xlsx文件出现的问题及解决,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-05-05
  • 使用Python自动生成HTML的方法示例

    使用Python自动生成HTML的方法示例

    这篇文章主要介绍了使用Python自动生成HTML的方法示例,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2019-08-08
  • python 实现汉诺塔游戏

    python 实现汉诺塔游戏

    这篇文章主要介绍了python 实现汉诺塔游戏的示例,帮助大家更好的理解和学习python,感兴趣的朋友可以了解下
    2020-11-11

最新评论