単純な関数__get__
の目的は何ですか、なぜ記述子クラス__get__
と異なった振る舞いをするのですか?単純な関数の__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
私たちが知っている記述子クラス__get__
メソッドのシグネチャobject.__get__(self, instance, owner)とそれが機能にa.__get__
署名と一致しないことのように見えます。
引数が渡されたとして、我々は機能上の(自己、例えば、所有者) '__get __'を呼び出すとき: 'self'は関数自体であり、インスタンスは' 2'であり、ownerは 'None'です。オプションであるためです。 関数 '__get__'メソッドは、関数自身が第1引数としてインスタンス(' self')を期待しているので、第1引数として常にインスタンスを渡すバインドされたメソッドを返します。インスタンスの代わりに '2'を渡すので、' a2'関数の最初の引数として '2'が渡されます。私は正しいですか? –
@ user1915011:私はあなたを理解しているか分からない。 'a .__ get__'は' a'が受け入れる引数を実際には気にしません。 'a .__ get__'に渡される' self'は、あなたが言うように、 'a'自身の関数です。 'a .__ get__'は' a'が受け入れる引数を調べるために "チェック"しません。 'a'が関数の場合、' a____'をインスタンス引数として渡さない限り、 'a .__ get__' * always *はバウンドメソッドオブジェクトを返します(アンバインドされたメソッドを返します)。 – BrenBarn