私は現在、関数をクラスにラップするデコレータを持っています。メソッドのクラスを返すデコレータを使用していますか?
(私たちは現在、各非同期呼び出しが定型コードのトンを持つクラスとして定義されているこの奇妙な、カスタムの非同期フレームワークを使用している。私の考えはただの関数を飾るし、適切なクラスを返すようにしました。)
このデコレータは、クラス外の関数でうまく動作します。しかし、メソッドでそれを使用する場合、引数は暗黙的に渡されることはなく、理由はわかりません。ここで
は、私はちょうどそう__init__
が呼び出されていないクラスを返す、一緒に
from __future__ import print_function
import functools
def test_wrap(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return wrapper
def test_class_wrap(func):
"""Return a Command object for use with the custom framework we are using."""
@functools.wraps(func, assigned=('__name__', '__module__'), updated=())
class Command(object):
def __init__(self, *args, **kwargs):
print("Args:", args)
print("Kwargs:", kwargs)
func(*args, **kwargs)
return Command
class MyObject(object):
def __init__(self):
self.value = 100
@test_wrap
def foo(self):
print(self.value)
@test_class_wrap
def bar(self):
print(self.value)
if __name__ == '__main__':
obj = MyObject()
obj.foo()
print()
obj.bar(obj) # works
# obj.bar() # TypeError: bar() takes exactly 1 argument (0 given)
# Why is self implicitly passed as an argument like with outher methods?
# Output
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
# Args: (<__main__.MyObject object at 0x7fe2bf9bb590>,)
# Kwargs: {}
# 100
。 。手動で行った場合、これがどのように機能するかを考えてください。デコレータがなければ、あるクラスを別のクラスに入れ子にしたコードを書いていましたか?もしそうなら、どうしたのですか?クラスはメソッドではないので、メソッドをクラスに置き換えるデコレータを使用すると、他のクラスの中にクラスが存在することになります。これはPythonではやや珍しい状況です。デコレータを使わずに 'MyObject'と' bar'を "手動で"書く方法の例を見せてもらえますか? – BrenBarn
この質問は、なぜ 'self'が' bar'に暗黙的に渡されないのかにもっと焦点を当てています。上のコードは、実際の使用ではなく、問題を再現します。私は、例を追加しようとすることができますが、それは多くの意味を理解することを期待しないでください – Shatnerz
あなたのクラスのインスタンスがないため、自己が渡されない理由です。 'self'はインスタンスを参照するので、インスタンス上でメソッドを呼び出すときだけ渡すことができますが、' obj.bar'は 'Command'と呼ばれる*クラス*です。 Commandクラスを別々に書いて、 'Command()'を呼び出そうとすると、同じエラーが発生します。 – BrenBarn