如何将函数名作为字符串获取?
def foo():
pass
>>> name_of(foo)
"foo"
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__
属性,因此您只需要记住一个特殊名称。
def wrapper(kwargs): super(ExtendedClass,self).call('wrapper', kwargs)
。你还有另一种选择,那就是:def wrapper(kwargs): super(ExtendedClass,self).call(sys._getframe().f_code.co_name, kwargs)
。所以,Albert Vonpupp的答案对我来说更好。 - Richard Gomesf.__name__ == 'f'
并不一定成立。 - wim若要从函数或方法内部获取当前函数或方法的名称,请考虑:
import inspect
this_function_name = inspect.currentframe().f_code.co_name
sys._getframe
也可以代替inspect.currentframe
,尽管后者避免了访问私有函数的问题。
如果想要获取调用函数的名称,请考虑使用f_back
,例如: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
sys._getframe
--它直接与CPython的内部连接。 - senderlesys._getframe(1).f_code.co_name
,这样您就可以定义一个名为 get_func_name()
的函数,并期望获得调用该函数的所需函数名称。 - m3nda如果您对类方法也感兴趣,Python 3.3+除了__name__
之外,还有__qualname__
。
def my_function():
pass
class MyClass(object):
def method(self):
pass
print(my_function.__name__) # gives "my_function"
print(MyClass.method.__name__) # gives "method"
print(my_function.__qualname__) # gives "my_function"
print(MyClass.method.__qualname__) # gives "MyClass.method"
MyClass.prop.fget.__qualname__
可以得到 MyClass.prop
。 - lapismy_function.func_name
函数还有其他有趣的属性。输入 dir(func_name)
列出它们。 func_name.func_code.co_code
是已编译的函数,存储为字符串。
import dis
dis.dis(my_function)
将以近乎人类可读的格式显示代码。 :)
__names__
是私有的,__names
是特殊的。 - gwideman_
表示其为私有变量(这只是一种约定俗成的做法),而双下划线 __
包围的变量名表示特殊变量。不确定在变量名前面添加双下划线是否具有任何形式上或惯例上的含义。 - MestreLionfunc_name
已经不存在了,如果想保持兼容性,需要使用func.__name__
。 - Daenyth这个函数将返回调用者的函数名称。
def func_name():
import traceback
return traceback.extract_stack(None, 2)[0][2]
就像Albert Vonpupp的回答一样,只是多了一个友好的包装。
import inspect
def foo():
print(inspect.stack()[0][3])
在哪里
stack()[0]
是调用者
stack()[3]
是方法的字符串名称
stack()[0]
总是调用者, [3]
是方法的字符串名称。 - kontur我喜欢使用函数装饰器。我添加了一个类,也会计算函数运行时间。假设 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():
如果您只想获取函数名称,这里有一个简单的代码。 假设您已经定义了这些函数。
def function1():
print "function1"
def function2():
print "function2"
def function3():
print "function3"
print function1.__name__
输出结果将会是function1
现在假设你有一个函数列表
a = [function1 , function2 , funciton3]
获取函数的名称
for i in a:
print i.__name__
输出结果将为
函数1
函数2
函数3
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)])
sys._getframe()
并不保证在所有 Python 实现中都能使用(参见参考文献),您可以使用 traceback
模块来完成相同的操作,例如:
import traceback
def who_am_i():
stack = traceback.extract_stack()
filename, codeline, funcName, text = stack[-2]
return funcName
调用stack[-1]
将返回当前进程的详细信息。
sys._getframe()
未定义,则traceback.extract_stack
也无法使用。后者提供了前者功能的粗略超集;您不能期望只看到其中一个。实际上,在IronPython 2.7中,extract_stack()
始终返回[]
。-1 - SingleNegationElimination
getattr(func, "__name__", str(func))
是我使用的方式,以防它是一个没有__name__
属性的Mock
(或其他对象)。 - Intrastellar Explorer