以下のコードで、関数自体の内部にあるpython関数の属性にアクセスできます:
_def aa():
print aa.__name__
print aa.__hash__
# other simliar
_
ただし、上記のaa()
関数が他のコードを記述するためのテンプレートである場合、たとえばbb()
の場合、次のように記述する必要があります。
_def bb():
print bb.__name__
print bb.__hash__
# other simliar
_
クラスメソッドのself
引数に似た「ポインタ」があるので、このようなコードを書くことができますか?
_def whatever():
print self.__name__
print self.__hash__
# other simliar
_
この問題を解決するためにクラスを使用すると言われている人を検索して見つけましたが、既存のすべての関数を再定義するのは面倒かもしれません。助言がありますか?
関数がそれ自体を参照するための一般的な方法はありません。代わりにデコレータの使用を検討してください。あなたが示したようにあなたが望むのがデコレータで簡単に実行できる関数に関する情報を印刷することだけだった場合:
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__
バインドされたメソッドを作成するために使用されるメソッド。デコレータは、単に既存のメソッドを使用して、関数をそれ自体のバインドされたメソッドにします。これはスタンドアロン関数でのみ機能します。メソッドがそれ自体を参照できるようにする場合は、元のソリューションのようなことを行う必要があります。
http://docs.python.org/library/inspect.html 有望に見えます:
import inspect
def foo():
felf = globals()[inspect.getframeinfo(inspect.currentframe()).function]
print felf.__name__, felf.__doc__
sys
モジュールを使用して、現在の関数の名前を取得することもできます。
import sys
def bar():
felf = globals()[sys._getframe().f_code.co_name]
print felf.__name__, felf.__doc__
少なくとも最初の行でself = bb
と言うことができます。そうすれば、他のすべての参照ではなく、関数名を変更するときにその行を変更するだけで済みます。
私のコードエディタは、クラスの場合と同じように変数self
を強調表示します。