如何在函数内部获取函数名(或类似“自我”引用)?

3 投票
2 回答
2424 浏览
提问于 2025-04-16 16:25

这个回答提到,函数有一个内置的 __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()

另外,函数是“不可变”的,可以作为字典的键来存储。你不需要依赖函数的名字。这可能是个优点(也可能是个缺点),这要看你怎么使用。

撰写回答