gpt4 book ai didi

python - 如何将 super() 与一个参数一起使用?

转载 作者:IT老高 更新时间:2023-10-28 20:47:30 25 4
gpt4 key购买 nike

在阅读 super() 上的 Python 文档时,我偶然发现了以下声明:

If the second argument is omitted, the super object returned is unbound.

“未绑定(bind)”是什么意思以及如何将 super() 与一个参数一起使用?

最佳答案

Python 函数对象是 descriptors , Python 使用描述符协议(protocol)将函数绑定(bind) 到一个实例。这个过程产生一个绑定(bind)方法

绑定(bind)是在您调用方法时使“魔术”self 参数出现的原因,也是在您尝试使用该属性时使 property 对象自动调用方法的原因作为实例的属性。

super() 当你尝试使用它来查找父类上的方法时,带有两个参数的

super() 会调用相同的描述符协议(protocol); super(Foo, self).bar() 将遍历 Foo 父类,直到找到属性 bar ,如果那是一个对象那是一个描述符,它将绑定(bind)到 self。调用 bar 然后调用绑定(bind)方法,该方法又调用 self 参数作为 bar(self) 传递的函数。

为此,super() 对象存储要绑定(bind)的类(第一个参数)和 self(第二个参数), self 参数的类型分别作为属性 __thisclass____self____self_class__:

>>> class Foo:
... def bar(self):
... return 'bar on Foo'
...
>>> class Spam(Foo):
... def bar(self):
... return 'bar on Spam'
...
>>> spam = Spam()
>>> super(Spam, spam)
<super: <class 'Spam'>, <Spam object>>
>>> super(Spam, spam).__thisclass__
<class '__main__.Spam'>
>>> super(Spam, spam).__self__
<__main__.Spam object at 0x107195c10>
>>> super(Spam, spam).__self_class__
<class '__main__.Spam'>

查找属性时,会搜索 __self_class__ 属性的 __mro__ 属性,从 __thisclass__ 的位置开始,然后结果是有约束的。

super() 只有 one 参数将其 __self____self_class__ 属性设置为 没有并且不能进行查找:

>>> super(Spam)
<super: <class 'Spam'>, NULL>
>>> super(Spam).__self__ is None
True
>>> super(Spam).__self_class__ is None
True
>>> super(Spam).bar
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'super' object has no attribute 'bar'

对象确实支持描述符协议(protocol),所以你可以像绑定(bind)方法一样绑定(bind)它:

>>> super(Spam).__get__(spam, Spam)
<super: <class 'Spam'>, <Spam object>>
>>> super(Spam).__get__(spam, Spam).bar()
'bar on Foo'

这意味着您可以将这样的对象存储在一个类中,并使用它来遍历父方法:

>>> class Eggs(Spam):
... pass
...
>>> Eggs.parent = super(Eggs)
>>> eggs = Eggs()
>>> eggs.parent
<super: <class 'Eggs'>, <Eggs object>>
>>> eggs.parent.bar()
'bar on Spam'

主要用例是避免每次都使用 super() 的双参数形式重复该类:

class Foo:
def __init_subclass__(cls, **kwargs):
super().__init_subclass__(**kwargs)
# class-private attribute so subclasses don’t clobber one another
setattr(cls, f'_{cls.__name__}__parent', super(cls))

def bar(self):
return 'bar on Foo'

class Spam(Foo):
def bar(self):
return 'spammed: ' + self.__parent.bar()

但是在使用类方法时会中断(因为 cls.__parent 不会绑定(bind))并且已被 Python 3 的 super() 取代,其参数为零从闭包中升级类:

class Foo:
def bar(self):
return 'bar on Foo'

class Spam(Foo):
def bar(self):
return 'spammed: ' + super().bar()

关于python - 如何将 super() 与一个参数一起使用?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30190185/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com