时间:2021-05-22
子类里访问父类的同名属性,而又不想直接引用父类的名字,因为说不定什么时候会去修改它,所以数据还是只保留一份的好。其实呢,还有更好的理由不去直接引用父类的名字,参见 Python's super() considered super! | Deep Thoughts by Raymond Hettinger。
这时候就该 super() 登场啦——
复制代码 代码如下:
class A:
def m(self):
print('A')
class B(A):
def m(self):
print('B')
super().m()
B().m()
当然 Python 2 里 super() 是一定要参数的,所以得这么写:
复制代码 代码如下:
class B(A):
def m(self):
print('B')
super(B, self).m()
需要提到自己的名字。这个名字也是动态查找的,在这种情况下替换第三方库中的类会出问题。
super() 很好地解决了访问父类中的方法的问题。那么,如果要访问父类的父类(准确地说,是方法解析顺序(MRO)中位于第三的类)的属性呢?
比如,B 类是继承 A 的,它重写了 A 的 m 方法。现在我们需要一个 C 类,它需要 B 类的一些方法,但是不要 B 的 m 方法,而改用 A 的。怎么间接地引用到 A 的 m 方法呢?使用self.__class__肯定是不行的,因为 C 还可能被进一步继承。
从文档中我注意到,super 的实现是通过插入一个名为 __class__ 的名字来实现的(super 会从调用栈里去查找这个 __class__ 名字)。所以,就像文档里暗示的,其实可以直接在定义方法时访问 __class__ 名字,它总是该方法被定义的类。继续我们的单字母类:
复制代码 代码如下:
class C(B):
def m(self):
print('C')
# see the difference!
print(__class__.__mro__)
print(self.__class__.__mro__)
__class__.__mro__[2].m(self)
class D(C):
def m(self):
print('D')
super().m()
o = D()
o.m()
会得到:
复制代码 代码如下:
D
C
(<class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)
(<class 't.D'>, <class 't.C'>, <class 't.B'>, <class 't.A'>, <class 'object'>)
A
不过,PyPy 并不支持这个 __class__ 名字。
声明:本页内容来源网络,仅供用户参考;我单位不保证亦不表示资料全面及准确无误,也不保证亦不表示这些资料为最新信息,如因任何原因,本网内容或者用户因倚赖本网内容造成任何损失或损害,我单位将不会负任何法律责任。如涉及版权问题,请提交至online#300.cn邮箱联系删除。
前面简单介绍了Python元组基本操作,这里再来简单讲述一下Python字典相关操作>>>dir(dict)#查看字段dict的属性和方法['__class__
最新的CentOS8已经内置了Python2和Python3,出入Python2和Python3两个命令可以分别进入Python2和Python3。CentOS
Python的线程操作在旧版本中使用的是thread模块,在Python27和Python3中引入了threading模块,同时thread模块在Python3
到2019年初,Python3已经更新到了Python3.7.3,Python有两个大版本Python2和Python3,Python3是现在和未来的主流。本文
前言Python思想:“一切都是对象!”,最近发现python3和python2中print的用法有很多不同,python3中需要使用括号,缩进要使用4个空格(