a_g*_*est 8 python inheritance class-method python-3.6
我尝试从内部访问父类的类方法,__init_subclass__
但似乎不起作用.假设以下示例代码:
class Foo:
def __init_subclass__(cls):
print('init', cls, cls.__mro__)
super(cls).foo()
@classmethod
def foo(cls):
print('foo')
class Bar(Foo):
pass
Run Code Online (Sandbox Code Playgroud)
这会产生以下异常:
AttributeError: 'super' object has no attribute 'foo'
Run Code Online (Sandbox Code Playgroud)
cls.__mro__
然而,这表明它Foo
是其中的一部分:(<class '__main__.Bar'>, <class '__main__.Foo'>, <class 'object'>)
.
所以我不明白为什么super(cls).foo()
不派遣Foo.foo
.有人可以解释一下吗?
aba*_*ert 11
普通super
对象(您通常从调用super(MyType, self)
或super()
或获得的对象super(MyType, myobj)
)跟踪它所创建的类型和对象.无论何时查找属性super
,它都会MyType
以方法解析顺序跳过,但如果找到方法,则会将其绑定到该self
对象.
未绑定super
有没有self
对象.所以,super(cls)
跳过cls
MRO找到方法foo
,然后将它绑定到... oops,它没有任何东西可以调用它.
那么,你可以称之为classmethod
什么?类本身或其子类,或该类或子类的实例.所以,其中任何一个都将作为第二个参数super
,最明显的一个是:
super(cls, cls)
Run Code Online (Sandbox Code Playgroud)
这有点类似于staticmethods之间的区别(bound staticmethods
实际上绑定到什么都没有)和classmethods
(bound classmethods
绑定到类而不是实例),但它并不那么简单.
如果您想知道为什么未绑定super
不起作用,您必须了解未绑定的super
内容.不幸的是,文档中唯一的解释是:
如果省略第二个参数,则返回的超级对象是未绑定的.
这是什么意思?好吧,您可以尝试从第一原则开始,将其与未绑定方法的含义并行(当然,未绑定的方法不是现代Python中的东西),或者您可以阅读C源代码,或2.2的类型统一super
的原始介绍(包括纯Python 克隆).
甲super
对象具有__self__
属性,就像一个方法的对象.并且正如它一样super(cls)
缺少它.1__self__
str.split
您不能以未绑定方法的方式super
显式使用未绑定(例如,str.split('123', '2')
相同'123'.split('2')
但super(cls).foo(cls)
不相同super(cls, cls).foo()
).但是你可以隐式使用它们,就像你对未绑定方法一样,而不用考虑它.
如果您不知道方法是如何工作的,那么tl'dr是:当您评估时myobj.mymeth
,Python查找mymeth
,找不到它myobj
,但确实在类型上找到它,因此它检查它是否是非数据描述符,如果是这样,则调用其__get__
方法将其绑定到myobj
.
因此,未绑定方法2是非数据描述符,其__get__
方法返回绑定方法.未绑定的@classmethod
s类似,但它们__get__
忽略该对象并返回绑定到该类的绑定方法.等等.
未绑定的super
s是非数据描述符,其__get__
方法返回一个绑定super
.
示例(wim为我提供了最接近未绑定使用的东西super
):
class A:
def f(self): print('A.f')
class B(A):
def f(self): print('B.f')
b = B()
bs = super(B)
B.bs = bs
b.bs.f()
Run Code Online (Sandbox Code Playgroud)
我们创建了一个绑定的超级bs
,把它贴类型B
,然后b.bs
是一个正常的绑定超好,所以b.bs.f
就是A.f
,就像super().f
本来是一个内部的B
方法.
你为什么想这么做?我不确定.我在Python中编写了各种可笑的动态和反射代码(例如,对于其他解释器的透明代理),我不记得曾经需要一个未绑定的代码super
.但如果你需要它,它就在那里.
我在这里作弊.首先,未绑定的方法在Python 3中不再是一个东西 - 但函数的工作方式相同,因此Python使用它们来使用未绑定的方法.其次,str.split
作为一个C内置,即使在2.x中也不是一种不受约束的方法 - 但它无论如何都会像一个人一样,至少就我们所关注的而言.
2.实际上是普通的功能.
归档时间: |
|
查看次数: |
318 次 |
最近记录: |