関数がそれ自体を参照する一般的な方法はありません。代わりにデコレータの使用を検討してください。あなたが示したように、デコレータで簡単に実行できる関数に関する情報を出力することだけが必要な場合:
from functools import wraps
def showinfo(f):
@wraps(f)
def wrapper(*args, **kwds):
print(f.__name__, f.__hash__)
return f(*args, **kwds)
return wrapper
@showinfo
def aa():
pass
本当に関数を参照する必要がある場合は、関数の引数に追加してください:
def withself(f):
@wraps(f)
def wrapper(*args, **kwds):
return f(f, *args, **kwds)
return wrapper
@withself
def aa(self):
print(self.__name__)
# etc.
編集して代替デコレータを追加します。
ラップされた関数を Python のイントロスペクションで正しく動作させる、より単純な (そしておそらくより高速な) デコレーターを作成することもできます。
def bind(f):
"""Decorate function `f` to pass a reference to the function
as the first argument"""
return f.__get__(f, type(f))
@bind
def foo(self, x):
"This is a bound function!"
print(self, x)
>>> foo(42)
<function foo at 0x02A46030> 42
>>> help(foo)
Help on method foo in module __main__:
foo(self, x) method of builtins.function instance
This is a bound function!
これは Python の記述子プロトコルを利用します。関数には、__get__
バインドされたメソッドを作成するために使用されるメソッドがあります。デコレーターは単に既存のメソッドを使用して、関数をそれ自体のバインドされたメソッドにします。メソッドがそれ自体を参照できるようにしたい場合は、元のソリューションに似た何かを行う必要があります。