在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?
当前回答
我建议不要依赖于堆栈元素。如果有人在不同的上下文中使用你的代码(例如python解释器),你的堆栈将改变并破坏你的索引([0][3])。
我建议你这样做:
class MyClass:
def __init__(self):
self.function_name = None
def _Handler(self, **kwargs):
print('Calling function {} with parameters {}'.format(self.function_name, kwargs))
self.function_name = None
def __getattr__(self, attr):
self.function_name = attr
return self._Handler
mc = MyClass()
mc.test(FirstParam='my', SecondParam='test')
mc.foobar(OtherParam='foobar')
其他回答
.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 inspect
def foo():
print(inspect.stack()[0][3])
print(inspect.stack()[1][3]) # will give the caller of foos name, if something called foo
foo()
输出:
喷火 < module_caller_of_foo >
我把这个实用工具放在附近:
import inspect
myself = lambda: inspect.stack()[1][3]
用法:
myself()
这是一个经得起考验的方法。
将@CamHart和@Yuval的建议与@RoshOxymoron接受的答案结合起来,可以避免:
_hidden和潜在弃用的方法 在堆栈中建立索引(可以在未来的python中重新排序)
所以我认为这对未来的python版本(在2.7.3和3.3.2测试)很有帮助:
from __future__ import print_function
import inspect
def bar():
print("my name is '{}'".format(inspect.currentframe().f_code.co_name))
更新:在3.7.10,3.8.10和3.9.5测试
从上面所有使用inspect库的答案来看,所有的都是这样写的:
import inspect
inspect.stack()[0][3]
但是,由于inspect.stack()的返回,[0]是一个NamedTuple,其形式为:
FrameInfo(frame=<frame at 0x103578810, file '<stdin>', line 1, code <module>>, filename='<stdin>', lineno=1, function='<module>', code_context=None, index=None)
可以简单地通过名称调用,即inspect.stack()[0].function
这里可以看到一个小的虚拟例子:
def test_train_UGRIZY_noZ(self, architecture, dataset, hyperrun, wloss):
log.warning(f"{inspect.stack()[0].function} -- Not Implemented Yet")
pass
当运行时打印:
WARNING - test_train_UGRIZY_noZ -- Not Implemented Yet