40

以下のコードで、関数自体の内部にある 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

この問題を解決するためにクラスを使用するという人を検索したところ、既存の関数をすべて再定義するのは面倒かもしれません。助言がありますか?

4

4 に答える 4

34

関数がそれ自体を参照する一般的な方法はありません。代わりにデコレータの使用を検討してください。あなたが示したように、デコレータで簡単に実行できる関数に関する情報を出力することだけが必要な場合:

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__バインドされたメソッドを作成するために使用されるメソッドがあります。デコレーターは単に既存のメソッドを使用して、関数をそれ自体のバインドされたメソッドにします。メソッドがそれ自体を参照できるようにしたい場合は、元のソリューションに似た何かを行う必要があります。

于 2011-02-21T08:37:04.267 に答える
16

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__
于 2011-02-21T08:23:30.447 に答える
-4

次のように、自分の「自己」名を作成するための簡単なハックはどうですか。

>>> def f():
...     self = f
...     print "My name is ", self.__name__, "and I am", self.__hash__
...
>>> f()
My name is  f and I am <method-wrapper '__hash__' of function object at 0x00B50F30>
>>> x = f
>>> x()
My name is  f and I am <method-wrapper '__hash__' of function object at 0x00B50F30>
>>>
于 2012-08-07T14:24:10.340 に答える