super()返回一个描述符,并且需要两项:
- 搜索类层次结构的起点。
- 绑定 返回方法的参数。
对于两个参数(和隐式零参数*),第二个参数用于绑定,但是如果不传递第二个参数,
super()则无法调用描述符协议来绑定返回的函数,类方法,属性或其他描述符。
classmethods仍然是描述符并已绑定;绑定到类而不是实例,但是
super()
不知道 描述符将如何使用绑定到的上下文。
super()不应并且不知道您正在查找的是类方法而不是常规方法;类方法仅与常规方法不同,因为它们的
.__get__()方法行为不同。
为什么要绑定类方法?因为当您继承子类
Foo但 不
重写时
.hello(),调用会
Bar.hello()调用该
Foo.__dict__['hello']函数,并将其绑定到,
Bar并且您的第一个参数
hello(cls)将是该子类,而不是
Foo。
如果没有第二个参数,则
super()返回一个未绑定的对象,以后可以手动对其进行绑定。您可以使用实例
.__get__()提供的方法自己进行绑定
super():
class Bar(Foo): @classmethod def hello(cls): print 'hello, bar' super(Bar).__get__(cls, None).hello()
super().__get__()在没有上下文的实例上有效地返回具有上下文集的新
super()实例。在具有上下文的实例上
.__get__()返回
self;
它已经绑定。
*在Python 3中,
super()从绑定方法内部不带参数的调用将使用调用框架隐式地发现类型和绑定对象是什么,因此在这种情况下,您不再需要显式传递类型和对象参数。
__class__为此,Python 3实际上向方法添加了一个隐式闭包变量。请参阅PEP 3135,为什么Python 3.x的super()有魔力?



