super().__init__(*args, **kwargs) 做啥?
Posted
技术标签:
【中文标题】super().__init__(*args, **kwargs) 做啥?【英文标题】:What does super().__init__(*args, **kwargs) do?super().__init__(*args, **kwargs) 做什么? 【发布时间】:2021-11-26 05:57:06 【问题描述】:我不知道super().__init__(*args, **kwargs)
在这里做什么。
class B(type):
def __init__(self, *args, **kwargs):
self.a = 'a'
super().__init__(*args, **kwargs)
class A(metaclass=B):
pass
据我所知,super() 返回一个跟踪 MRO 中当前位置的超类的实例。当调用 super 实例的方法时,super 会查找 MRO 中的下一个类并调用该类的方法。
B.__mro__
(<class '__main__.B'>, <class 'type'>, <class 'object'>)
super().__init__(*args, **kwargs)
调用__init__
方法,是什么意思?
如果我删除它
class B(type):
def __init__(self, *args, **kwargs):
self.a = 'a'
class A(metaclass=B):
pass
初始化A
类
x=A()
x.a
'a'
实例x
属于A
类仍然拥有a
的属性,效果相同。
【问题讨论】:
它只是将任何位置和关键字参数传递给父级的“构造函数”。 在不将位置和关键字参数传递给父级的“构造函数”的情况下,效果相同。 它将这些参数传递给它的父构造函数,以便在它的构造中做任何需要做的事情,对于这个特定的例子来说,放置那条线或者不改变任何东西,但它可能需要更多精心设计的继承方案 请举个具体的例子。 【参考方案1】:这是一个简单的示例
>>> class A:
def __init__(self, a="a",*argv,**karg):
super().__init__(*argv,**karg)
self.a=a
>>> class B(A):
def __init__(self, b="b",*argv,**kargv):
super().__init__(*argv,**kargv)
self.b=b
>>> class Bad(B):
def __init__(self,b="bad",*arg,**kargv):
self.b=b
>>> b=B()
>>> b.a
'a'
>>> b.b
'b'
>>> bad=Bad()
>>> bad.b
'bad'
>>> bad.a
Traceback (most recent call last):
File "<pyshell#220>", line 1, in <module>
bad.a
AttributeError: 'Bad' object has no attribute 'a'
>>>
这里A
是我们的基类,我们希望它的任何子类都具有 A 的所有功能以及子类所具有的任何额外功能,然后要添加新功能,我们只需将其子类化并使用 super 委托给我们的父类A
知道怎么做,所以我们不重复那些部分,这里B
是一个坚持这个原则的子类。
现在Bad
是一个不遵守此原则的子类,因此不会在A
父级的构造中设置任何功能,因此它不会设置其.a
属性,因为它通过不通过 super 调用其父构造函数来拒绝合作。
一些相关的解释视频: Raymond Hettinger - Super considered super! - PyCon 2015
【讨论】:
以上是关于super().__init__(*args, **kwargs) 做啥?的主要内容,如果未能解决你的问题,请参考以下文章