デコレータでローカルに定義された関数を使用する方法を知っています。私は以下のdecorator1
でこれを行います。Python:デコレータ内のラッパーとしてローカル関数の代わりに呼び出し可能オブジェクトを使用する
しかし、私はそれが非常にきれいであるとは思わないし、私はそれに酸洗問題を経験した。
私はデコレータが呼び出し可能オブジェクトを返すようにしたいと思います。私は次のコード
def decorator1(f):
def wrapped(*args,**kwargs):
print(f,' is being called with ',args,kwargs)
return f(*args,**kwargs)
return wrapped
def decorator2(f):
return Wrapped(f)
class Wrapped():
def __init__(self,f):
self.f=f
def __call__(self,*args,**kwargs):
print(self.f,' is being called with ',args,kwargs)
return self.f(*args,**kwargs)
class A():
@decorator1
def foo1(self,x):
return x+1
@decorator2
def foo2(self,x):
return x+1
a=A()
a.foo1(0)
a.foo2(0)
を実行すると、私は
<function A.foo1 at 0x7efe64641f28> is being called with (<__main__.A object at 0x7efe65b3b3c8>, 0) {}
<function A.foo2 at 0x7efe6464c0d0> is being called with (0,) {}
Traceback (most recent call last):
File "/home/wolfersf/Dropbox/Professional/Projects/swutil/swutil/test.py", line 28, in <module>
a.foo2(0)
File "/home/wolfersf/Dropbox/Professional/Projects/swutil/swutil/test.py", line 15, in __call__
return self.f(*args,**kwargs)
TypeError: foo2() missing 1 required positional argument: 'x'
を得ることがa
が<Wrapped_instance>.__call__
の*args
で渡されていないようだ。しかし、私は問題に実行しています。
私はa.foo2(0)
が<a.foo2>(a,0)
に変換することを考えているだろうが<Wrapped_instance>(a,0)
に変換<Wrapped_instance>.__call__(a,0)
に変換私は間違って何をやっている<<Wrapped_instance>.__call__>(<Wrapped_instance>,a,0)
に変換?
これは本当に適切な解決策です。それがうまくいかなかった理由については、Pythonが関数をメソッドに変換する方法を理解する必要があります。これについては、ここで説明します:https://wiki.python.org/moin/FromFunctionToMethodこの文書を読んだ後もまだ不明な点がある場合は教えてください。完全な回答を投稿します。 –
私は思っています。私の思考連鎖の最初の部分は間違っていたと思います。 'a.fict2'は' a .__ dict __ ['foo2']>(a、0) 'foo2'] 'は' Wrapped'のインスタンスです。この変換は 'a .__ dict __ ['foo2']'が 'function'型であるとき、または手作業で翻訳を行う' __get__'メソッドを装備するときにのみ起こります – Bananach