我想问简单函数的目的是什么__get__以及为什么 if 的行为与描述符类不同__get__?
我的调查:
import inspect
def a(x, y):
return x + y
def wr(f):
def wrapper(*args, **kwargs):
print f.__name__, 'called with', args, kwargs
return f(*args, **kwargs)
return wrapper
print inspect.getsource(a)
# def a(x, y):
# return x + y
print inspect.getsource(a.__get__) # we cannot inspect it because it is a method-wrapper
# Traceback (most recent call last):
# ...
# 'function, traceback, frame, or code object'.format(object))
# TypeError: <method-wrapper '__get__' of function object at 0x7fd43591e140> is not a module, class, method, function, traceback, frame, or code object
a.__get__ = wr(a.__get__) # replace with function that delegates work and prints passed arguments
a2 = a.__get__(2) # we can use __get__ for functools.partial purposes
# __get__ called with (2,) {}
print a.__class__, a2.__class__ # it looks like a is a normal function and a2 is a bound function, but there is no instance
# <type 'function'> <type 'instancemethod'>
print 'a2 result:', a2(3)
# a2 result: 5
print inspect.getsource(a2) # source the same as function a
# def a(x, y):
# return x + y
Run Code Online (Sandbox Code Playgroud)
我们知道描述符类__get__方法签名object.__get__(self,instance,owner),它看起来与函数a.__get__签名不匹配。
Python 函数是描述符。这就是方法对象的创建方式。当您这样做时obj.method,描述符协议被激活,并且函数的__get__方法被调用。这将返回一个绑定方法。
这就是为什么您将其视为a2实例方法。当您这样做时a.__get__(2),您将2作为“实例”参数传递给__get__。如果你这样做print(a2),你会看到<bound method ?.a of 2>,表明Python认为a2是该对象的绑定方法2。
该owner参数在描述符协议中是可选的(或者至少在它的函数实现中),这就是为什么您只能__get__使用一个参数进行调用。您可以调用a.__get__(2, 1)并取回类似的对象。
| 归档时间: |
|
| 查看次数: |
5394 次 |
| 最近记录: |