gpt4 book ai didi

python - 函数、未绑定(bind)方法和绑定(bind)方法有什么区别?

转载 作者:IT老高 更新时间:2023-10-28 20:24:11 26 4
gpt4 key购买 nike

我问这个问题是因为 this answer 的评论线程上的讨论。 .我已经完成了 90% 的工作。

In [1]: class A(object):  # class named 'A'
...: def f1(self): pass
...:
In [2]: a = A() # an instance

f1以三种不同的形式存在:

In [3]: a.f1  # a bound method
Out[3]: <bound method a.f1 of <__main__.A object at 0x039BE870>>
In [4]: A.f1 # an unbound method
Out[4]: <unbound method A.f1>
In [5]: a.__dict__['f1'] # doesn't exist
KeyError: 'f1'
In [6]: A.__dict__['f1'] # a function
Out[6]: <function __main__.f1>

绑定(bind)方法未绑定(bind)方法函数对象有什么区别,都是f1描述的?如何称呼这三个对象?它们如何相互转化? documentation对这些东西很难理解。

最佳答案

functiondef 语句或 lambda 创建。在 Python 2 下,当一个函数出现在 class 语句的主体中(或传递给 type 类构造调用)时,它会被转换为 unbound方法。 (Python 3 没有未绑定(bind)的方法;见下文。)当在类实例上访问函数时,它会转换为 绑定(bind)方法,该方法会自动将该实例作为第一个方法提供给该方法self 参数。

def f1(self):
pass

这里f1是一个函数

class C(object):
f1 = f1

现在 C.f1 是一个未绑定(bind)的方法。

>>> C.f1
<unbound method C.f1>
>>> C.f1.im_func is f1
True

我们也可以使用type类的构造函数:

>>> C2 = type('C2', (object,), {'f1': f1})
>>> C2.f1
<unbound method C2.f1>

我们可以手动将 f1 转换为未绑定(bind)的方法:

>>> import types
>>> types.MethodType(f1, None, C)
<unbound method C.f1>

未绑定(bind)的方法通过对类实例的访问进行绑定(bind):

>>> C().f1
<bound method C.f1 of <__main__.C object at 0x2abeecf87250>>

访问被翻译成通过描述符协议(protocol)调用:

>>> C.f1.__get__(C(), C)
<bound method C.f1 of <__main__.C object at 0x2abeecf871d0>>

结合这些:

>>> types.MethodType(f1, None, C).__get__(C(), C)
<bound method C.f1 of <__main__.C object at 0x2abeecf87310>>

或直接:

>>> types.MethodType(f1, C(), C)                
<bound method C.f1 of <__main__.C object at 0x2abeecf871d0>>

函数和未绑定(bind)方法的主要区别在于,后者知道它绑定(bind)到哪个类;调用或绑定(bind)未绑定(bind)的方法需要其类类型的实例:

>>> f1(None)
>>> C.f1(None)
TypeError: unbound method f1() must be called with C instance as first argument (got NoneType instance instead)
>>> class D(object): pass
>>> f1.__get__(D(), D)
<bound method D.f1 of <__main__.D object at 0x7f6c98cfe290>>
>>> C.f1.__get__(D(), D)
<unbound method C.f1>

由于函数和未绑定(bind)方法之间的差异非常小,Python 3 gets rid of the distinction ;在 Python 3 下,访问类实例上的函数只会为您提供函数本身:

>>> C.f1
<function f1 at 0x7fdd06c4cd40>
>>> C.f1 is f1
True

那么,在 Python 2 和 Python 3 中,这三个是等价的:

f1(C())
C.f1(C())
C().f1()

将函数绑定(bind)到实例具有将其第一个参数(通常称为self)固定到实例的效果。因此,绑定(bind)方法 C().f1 等价于:

(lamdba *args, **kwargs: f1(C(), *args, **kwargs))
functools.partial(f1, C())

关于python - 函数、未绑定(bind)方法和绑定(bind)方法有什么区别?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/11949808/

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