gpt4 book ai didi

python - 不确定 Python 文档中关于用户定义方法对象的说法

转载 作者:行者123 更新时间:2023-12-01 04:01:28 25 4
gpt4 key购买 nike

来自 Python 语言引用 Data Models section ,在用户定义的方法标题下:

When the attribute is a user-defined method object, a new method object is only created if the class from which it is being retrieved is the same as, or a derived class of, the class stored in the original method object; otherwise, the original method object is used as it is.

这句话是什么意思?

最佳答案

当您在类或实例上查找名称时,Python 2 会绑定(bind)函数,请参阅 descriptor protocol 。在类上执行此操作时,结果是未绑定(bind)方法:

>>> class Foo(object):
... def bar(self):
... return 'Method bound to {!r}, from class Foo'.format(self)
... def __repr__(self):
... return '<Instance of type {!r}>'.format(type(self))
...
>>> Foo.bar
<unbound method Foo.bar>

该对象仍然包含对原始类以及原始函数对象的引用:

>>> Foo.bar.im_class
<class '__main__.Foo'>
>>> Foo.bar.__func__ # new name, old name im_self still works too
<function bar at 0x105d2a9b0>

这里的术语未绑定(bind)指的是它没有绑定(bind)到实例;但是它绑定(bind)到类。

文本告诉您,当您将此类未绑定(bind)方法对象粘贴到另一个类上时,它将像对待函数一样对待它们。因此,如果这样做,方法对象将反弹到新类;原来的函数对象被引用并反弹到新的类:

>>> class Bar(Foo):
... bar = Foo.bar # an unbound method from the Foo class!
...
>>> Bar.bar
<unbound method Bar.bar>
>>> Bar.bar.im_class
<class '__main__.Bar'>
>>> Bar().bar() # it'll work like any other method
"Method bound to <Instance of type <class '__main__.Bar'>>, from class Foo"

这里BarFoo的子类,未绑定(bind)的方法对象重新绑定(bind)到类Bar上。

但是,文本指出,如果将未绑定(bind)方法粘贴到不是 Foo 子类的其他类上,则不会完成此操作:

>>> class Baz(object):   # not derived from Foo
... bar = Foo.bar
...
>>> Baz.bar
<unbound method Foo.bar>
>>> Baz.bar.im_class
<class '__main__.Foo'>
>>> Baz().bar
<unbound method Foo.bar>
>>> Baz().bar()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: unbound method bar() must be called with Foo instance as first argument (got nothing instead)

您必须通过 Foo.bar.__func__ 访问原始函数,或者通过访问类 __dict__ 来完全规避描述符协议(protocol)(因此使用 Foo.__class__['bar']) 来完全避免这个问题。

引用文档中的文本相当困惑,因为这并不适用于完全绑定(bind)的方法,尽管它暗示它应该适用;即使在类上使用,它们也永远不会重新绑定(bind):

>>> class Spam(object):
... bar = Foo().bar # *bound* method, taken from an instance of Foo
...
>>> Spam.bar
<bound method Foo.bar of <Instance of type <class '__main__.Foo'>>>
>>> Spam().bar
<bound method Foo.bar of <Instance of type <class '__main__.Foo'>>>
>>> Spam().bar()
"Method bound to <Instance of type <class '__main__.Foo'>>, from class Foo"

Python 3 完全摆脱了未绑定(bind)的方法;从类对象中检索函数会得到原始函数对象。上述限制已完全取消。

关于python - 不确定 Python 文档中关于用户定义方法对象的说法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36420410/

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