如何在函数内部获取函数名(或类似“自我”引用)?
这个回答提到,函数有一个内置的 __name__
属性,可以在函数外部使用,比如 print f.__name__
。但是,我想知道如何在函数内部获取这个属性呢?
直接使用 __name__
是不行的:print __name__
会输出 __main__
。
在 f()
内部使用 print f.__name__
看起来很傻——我完全可以直接输入 "f"
。
另外,函数有没有类似于 self
的对象呢?也就是说,我能否以某种通用的方式获取正在执行的函数的指针?
我不喜欢在这个问题中提到的方法——感觉为了这么简单的事情去搞栈并不是正确的做法。
动机:我有一个 {keyword:function}
的字典,关键词是从输入中读取的,然后执行相应的函数。我希望每个函数只执行一次,所以我想让每个函数在执行时在某个数据结构中注册自己。我知道可以在字典中做到这一点,但我想用一个单独的数据结构来实现。
顺便说一下,Python 版本是 2.6.4。
2 个回答
4
如果你不想去“检查”堆栈的话,可以在你的方法上加一个装饰器,这样就能把它存到你的字典里,避免重复调用。
function_list = []
def method_singleton(function):
global function_list
def decorated_method(*args, **kwargs):
if function.__name__ not in function_list:
function_list.append(function.__name__)
return function(*args, **kwargs)
else:
print "Method %s already called"%function.__name__
return decorated_method
@method_singleton
def method_to_decorate(arg1, arg2):
pass
这里的“function_list”是已经调用过的函数列表(我不知道你是怎么管理你的字典的)。
3
也许你可以给每个你调用的函数加上一个叫做onlyonce
的装饰器?这样做会更符合Python的风格。下面是一个概念验证的例子。
called = set()
def onlyonce(fn):
def decorated(*largs, **kargs):
if fn not in called:
called.add(fn)
print "Calling"
fn(*largs, **kargs)
else:
print "Already called"
return decorated
@onlyonce
def test_function():
print "I am getting called now"
test_function()
test_function()
test_function()
test_function()
另外,函数是“不可变”的,可以作为字典的键来存储。你不需要依赖函数的名字。这可能是个优点(也可能是个缺点),这要看你怎么使用。