【问题标题】:how to get function's name from within the function (or kind of "self" reference to the function)?如何从函数中获取函数的名称(或对函数的“自我”引用)?
【发布时间】:2011-08-12 20:07:13
【问题描述】:

This answer 表示函数有一个内置的__name__ 属性,可以从函数外部 使用,即print f.__name__。但是,如何从 within 函数本身获取此属性?

仅使用不合格的__name__ 无济于事:print __name__ 打印出__main__

f() 中使用print f.__name__ 看起来很愚蠢——我也可以输入"f"

或者,是否有一种self 函数对象,即我可以获得指向以通用方式执行的函数的指针吗?

我不喜欢this question 中提出的方法 - 感觉为如此简单的任务破解堆栈不是正确的方法。

动机:我有一本{keyword:function} 的字典,从输入中读取关键字并执行适当的函数。我希望每个函数只执行一次,所以我希望每个函数在执行时将自己注册到某个数据结构中。我知道我可以在字典本身中做到这一点,但我想为此使用单独的数据结构。

Python 版本是 2.6.4 BTW

【问题讨论】:

  • 只需链接到这个答案,它解决了标题中的问题:stackoverflow.com/a/5067654/547578
  • 感谢@fossilet,但正如我在使用调用堆栈的问题中所说的那样感觉......不知道,太hacky
  • 我觉得你觉得 inspect 太“老套”很幽默。授予导航多维堆栈的语法可能需要阅读文档,但它是有效的。这是另一个可能很有趣的 hacky 方法:将函数作为参数传递给自身。

标签: python


【解决方案1】:

如果您不想“检查”堆栈,可以在方法上使用装饰器将其存储在字典中,避免启动两次。

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”是已经调用的函数列表(我不知道你如何管理你的字典)

【讨论】:

  • 现在我了解了装饰器,感谢您的回答 :),当定义和装饰函数时,您的解决方案不是只检查一次 function_list 吗?每次执行函数时,检查不应该是动态的吗?
  • 哦,是的,你是对的 ;) 要在调用时执行此操作,您必须将测试移动到修饰方法中
【解决方案2】:

也许您应该使用onlyonce 装饰器来装饰您正在调用的每个函数?那会更pythonic。下面是概念证明。

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()

此外,函数是“不可变的”,可以存储为字典键。您不必依赖名称。根据您的使用情况,这可能是一个优势(或一个劣势)。

【讨论】:

  • 谢谢,易卜拉欣。你的最后一段是说我可以做called[f]=True
  • 是的,但我使用集合而不是字典,因为您没有任何“值”来存储密钥。
  • 这并没有回答标题中的问题。
  • 它回答了应该被问到的问题,而这通常更有用。
猜你喜欢
  • 2010-09-19
  • 1970-01-01
  • 2011-01-10
  • 2021-04-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-07-02
相关资源
最近更新 更多