950

Pythonで、関数を呼び出さずに関数名を文字列として取得するにはどうすればよいですか?

def my_function():
    pass

print get_function_name_as_string(my_function) # my_function is not in quotes

出力する必要があります"my_function"

そのような関数はPythonで利用できますか?そうでない場合は、get_function_name_as_stringPythonで実装する方法についてのアイデアはありますか?

4

14 に答える 14

1235
my_function.__name__

__name__均一に適用されるため、を使用することをお勧めします。とは異なりfunc_name、組み込み関数でも機能します。

>>> import time
>>> time.time.func_name
Traceback (most recent call last):
  File "<stdin>", line 1, in ?
AttributeError: 'builtin_function_or_method' object has no attribute 'func_name'
>>> time.time.__name__ 
'time'

また、二重の下線は、これが特別な属性であることを読者に示しています。おまけとして、クラスとモジュールにも__name__属性があるため、特別な名前を 1 つしか覚えていません。

于 2008-11-01T00:07:17.713 に答える
363

内部から現在の関数またはメソッドの名前を取得するには、次のことを考慮してください。

import inspect

this_function_name = inspect.currentframe().f_code.co_name

sys._getframe代わりにinspect.currentframe機能しますが、後者はプライベート関数へのアクセスを回避します。

代わりに呼び出し元の関数の名前を取得するには、f_backas inを検討してinspect.currentframe().f_back.f_code.co_nameください。


も使用している場合mypy、次のように不平を言う可能性があります。

エラー: "Optional[FrameType]" の項目 "None" に属性 "f_code" がありません

上記のエラーを抑制するには、次のことを考慮してください。

import inspect
import types
from typing import cast

this_function_name = cast(types.FrameType, inspect.currentframe()).f_code.co_name
于 2012-11-22T13:59:49.493 に答える
47
my_function.func_name

関数には他にも楽しいプロパティがあります。それらをリストするためにタイプdir(func_name)します。func_name.func_code.co_codeコンパイルされた関数であり、文字列として格納されます。

import dis
dis.dis(my_function)

ほぼ人間が読める形式でコードを表示します。:)

于 2008-10-30T19:39:19.740 に答える
36

この関数は、呼び出し元の関数名を返します。

def func_name():
    import traceback
    return traceback.extract_stack(None, 2)[0][2]

これは、フレンドリーなラッパーを使用した Albert Vonpupp の回答のようなものです。

于 2013-12-21T00:59:58.403 に答える
28

関数デコレータを使用するのが好きです。関数の時間も計測するクラスを追加しました。gLog が標準の python ロガーであると仮定します。

class EnterExitLog():
    def __init__(self, funcName):
        self.funcName = funcName

    def __enter__(self):
        gLog.debug('Started: %s' % self.funcName)
        self.init_time = datetime.datetime.now()
        return self

    def __exit__(self, type, value, tb):
        gLog.debug('Finished: %s in: %s seconds' % (self.funcName, datetime.datetime.now() - self.init_time))

def func_timer_decorator(func):
    def func_wrapper(*args, **kwargs):
        with EnterExitLog(func.__name__):
            return func(*args, **kwargs)

    return func_wrapper

これで、関数で行う必要があるのは、関数を装飾するだけです。

@func_timer_decorator
def my_func():
于 2016-07-19T08:37:30.777 に答える
19

@Demyn's answer の拡張として、現在の関数の名前と現在の関数の引数を出力するいくつかのユーティリティ関数を作成しました。

import inspect
import logging
import traceback

def get_function_name():
    return traceback.extract_stack(None, 2)[0][2]

def get_function_parameters_and_values():
    frame = inspect.currentframe().f_back
    args, _, _, values = inspect.getargvalues(frame)
    return ([(i, values[i]) for i in args])

def my_func(a, b, c=None):
    logging.info('Running ' + get_function_name() + '(' + str(get_function_parameters_and_values()) +')')
    pass

logger = logging.getLogger()
handler = logging.StreamHandler()
formatter = logging.Formatter(
    '%(asctime)s [%(levelname)s] -> %(message)s')
handler.setFormatter(formatter)
logger.addHandler(handler)
logger.setLevel(logging.INFO)

my_func(1, 3) # 2016-03-25 17:16:06,927 [INFO] -> Running my_func([('a', 1), ('b', 3), ('c', None)])
于 2016-03-25T21:21:23.133 に答える
17

sys._getframe()Python のすべての実装で使用できるとは限りません ( ref を参照)。tracebackモジュールを使用して同じことを行うことができます。

import traceback
def who_am_i():
   stack = traceback.extract_stack()
   filename, codeline, funcName, text = stack[-2]

   return funcName

を呼び出すとstack[-1]、現在のプロセスの詳細が返されます。

于 2013-08-31T00:34:37.407 に答える