在Python中,如果不使用traceback模块,是否有一种方法可以从函数内部确定函数的名称?
假设我有一个模块foo和一个功能栏。当执行foo.bar()时,是否有一种方法让bar知道bar的名字?或者更好的是,foo。酒吧的名字吗?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
在Python中,如果不使用traceback模块,是否有一种方法可以从函数内部确定函数的名称?
假设我有一个模块foo和一个功能栏。当执行foo.bar()时,是否有一种方法让bar知道bar的名字?或者更好的是,foo。酒吧的名字吗?
#foo.py
def bar():
print "my name is", __myname__ # <== how do I calculate this at runtime?
当前回答
这很容易用装饰器完成。
>>> from functools import wraps
>>> def named(func):
... @wraps(func)
... def _(*args, **kwargs):
... return func(func.__name__, *args, **kwargs)
... return _
...
>>> @named
... def my_func(name, something_else):
... return name, something_else
...
>>> my_func('hello, world')
('my_func', 'hello, world')
其他回答
我想检查是最好的方法。例如:
import inspect
def bar():
print("My name is", inspect.stack()[0][3])
实现您自己的装饰器
# mydecorators.py
def resolve_function(func):
#in case annotated func is an staticmethod
if isinstance(func,staticmethod):
return func.__func__
return func
def print_my_name(func):
def function_caller(*args,**kwargs):
_func = resolve_function(func)
print("my name is: %s" %_func.__name__)
return _func(*args,**kwargs)
return function_caller
然后使用它
# foo.py
from mydecorators import *
@print_my_name
def bar():
#do something else
#in terminal: my name is: bar
我把这个实用工具放在附近:
import inspect
myself = lambda: inspect.stack()[1][3]
用法:
myself()
.f_back.f_code Sincesys._getframe()。Co_name在python 3.9中根本不起作用,下面可以从现在开始使用:
from inspect import currentframe
def testNameFunction() -> str:
return currentframe().f_back.f_code.co_name
print(f'function name is {testNameFunction()}(...)')
结果:
function name is testNameFunction(...)
我不知道为什么人们会把它弄得这么复杂:
import sys
print("%s/%s" %(sys._getframe().f_code.co_filename, sys._getframe().f_code.co_name))