首先看一下super()函数的定义:
super([type [,object-or-type]])
Return a **proxy object** that delegates method calls to a **parent or sibling** class of type.
返回一个代理对象, 这个对象负责将方法调用分配给第一个参数的一个父类或者同辈的类去完成.
parent or sibling class 如何确定"htmlcode">
super()实际返回的是一个代理的super对象! 调用super()这个构造方法时, 只是返回一个super()对象, 并不做其他的操作. 然后对这个super对象进行方法调用时, 发生的事情如下: 找到第一个参数的__mro__列表中的下一个直接定义了该方法的类, 并实例化出一个对象 举个例子: 在A的构造方法中, 先调用super()得到一个super对象, 然后向这个对象调用init方法, 这是super对象会搜索A的__mro__列表, 找到第一个定义了__init__方法的类, 于是就找到了Root, 然后调用Root.__init__(self), 这里的self是super()的第二个参数, 是编译器自动填充的, 也就是A的__init__的第一个参数, 这样就完成对__init__方法调用的分配. 注意: 在许多语言的继承中, 子类必须调用父类的构造方法, 就是为了保证子类的对象能够填充上父类的属性! 而不是初始化一个父类对象...(我之前就一直是这么理解的..). Python中就好多了, 所谓的调用父类构造方法, 就是明明白白地把self传给父类的构造方法, 我的小身子骨就这么交给你了, 随便你怎么折腾吧:joy: 参数说明 如果提供了第二个参数, 则找到的父类对象的self就绑定到这个参数上, 后面调用这个对象的方法时, 可以自动地隐式传递self. 如果没有传递第二个参数, 那么返回的对象就是Unbound, 调用这个unbound对象的方法时需要手动传递第一个参数, 类似于Base.__int__(self, a, b). 不带参数的super()只能用在类定义中(因为依赖于caller的第二个参数), 编译器会自动根据当前定义的类填充参数. super()的两种常见用法: 单继承中, super用来指代隐式指代父类, 避免直接使用父类的名字 对面向对象的理解 其实我觉得Python里面这样的语法更容易理解面向对象的本质, 比Java中隐式地传this更容易理解. 所谓函数, 就是一段代码, 接受输入, 返回输出. 所谓方法, 就是一个函数有了一个隐式传递的参数. 所以方法就是一段代码, 是类的所有实例共享的, 唯一不同的是各个实例调用的时候传给方法的this 或者self不一样而已. 构造方法是什么呢? 其实也是一个实例方法啊, 它只有在对象生成了之后才能调用, 所以Python中__init__方法的参数是self啊. 调用构造方法时其实已经为对象分配了内存, 构造方法只是起到初始化的作用, 也就是为这段内存里面赋点初值而已. Java中所谓的静态变量其实也就是类的变量, 其实也就是为类也分配了内存, 里面存了这些变量, 所以Python中的类对象我觉得是很合理的, 也比Java要直观. 至于静态方法, 那就与对象一点关系都没有了, 本质就是个独立的函数, 只不过写在了类里面而已. 而Python中的classmethod其实也是一种静态方法, 不过它会依赖于cls对象, 这个cls就是类对象, 但是只要想用这个方法, 类对象必然是存在的, 不像实例对象一样需要手动的实例化, 所以classmethod也可以看做是一种静态变量. 而staticmethod就是真正的静态方法了, 是独立的函数, 不依赖任何对象. Java中的实例方法是必须依赖于对象存在的, 因为要隐式的传输this, 如果对象不存在这个this也没法隐式了. 所以在静态方法中是没有this指针的, 也就没法调用实例方法. 而Python中的实例方法是可以通过类名来调用的, 只不过因为这时候self没办法隐式传递, 所以必须得显式地传递.
class Root:
pass
class A(Root):
pass
class B(Root):
pass
class C(A, B):
pass
print(C.__mro__)
# 输出结果为:
# (<class '__main__.C'>, <class '__main__.A'>, <class '__main__.B'>, <class '__main__.Root'>, <class 'object'>)
然后将这个对象的self变量绑定到第二个参数上, 返回这个对象
class Root:
def __init__(self):
print('Root')
class A(Root):
def __init__(self):
super().__init__() # 等同于super(A, self).__init__()
super() -> same as super(__class__, <first argument>) # <first argument>指的是调用super的函数的第一个参数
super(type) -> unbound super object
super(type, obj) -> bound super object; requires isinstance(obj, type)
super(type, type2) -> bound super object; requires issubclass(type2, type)
Typical use to call a cooperative superclass method:
class C(B):
def meth(self, arg):
super().meth(arg)
This works for class methods too:
class C(B):
@classmethod
def cmeth(cls, arg):
super().cmeth(arg)
如果第二个参数是一个对象, 则isinstance(obj, type)必须为True. 如果第二个参数为一个类型, 则issubclass(type2, type)必须为True
也就是说, 后面所有调用super返回对象的方法时, 第一个参数self都是super()的第二个参数. 因为Python中所谓的方法, 就是一个第一个参数为self的函数, 一般在调用方法的时候a.b()会隐式的将a赋给b()的第一个参数.
多继承中, 解决Diamond问题 (TODO)
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 魔兽世界wlk敏锐贼一键输出宏是什么 wlk敏锐贼一键输出宏介绍
- 李逸朗2007-李威乐[英皇娱乐][WAV+CUE]
- DavidVersace-EyetoEye(2024)[24-44,1]
- SimoneLamsma,RobertKulek-Mendelssohn,Janacek,Schumann-SonatasforViolinandPiano【SAC
- 《街头篮球》大动作:新增五大服务器节点 优化玩家体验
- 任天堂宣布推出音乐APP!仅面向NSO订阅用户
- 《马路RPG:兄弟齐航》新预告!兄弟携手海岛冒险
- 王子鸣.2009-永远【九洲】【WAV分轨】
- 杭天琪.2002-水与火的缠绵【泰达】【WAV+CUE】
- 邱锋泽.2024-COlOR.Free【发现梦想】【FLAC分轨】
- 群星 《10年朋友Vol.8》滚石台湾版[WAV+CUE][1.G]
- 群星《2024好听新歌31》十倍音质 U盘音乐 [WAV分轨][1.1G]
- 群星《全天后》华纳[WAV+CUE][1.1G]
- 许乐《声愿HQCD》[正版原抓WAV+CUE]
- 黄凯芹《给你留念》头版限量编号MQA-UHQCD2024[低速原抓WAV+CUE]