如何在函数内部获取函数对象(Python) [英] How to get function object inside a function (Python)
问题描述
我想要类似的东西
def x():
print get_def_name()
,但不一定知道x
的名称.
but not necessarily know the name of x
.
理想情况下,它将返回'x'
,其中x是函数的名称.
Ideally it would return 'x'
where x would be the name of the function.
推荐答案
Python中的函数是对象,并且碰巧这些对象确实具有包含其定义名称的属性:
Functions in Python are objects, and as it happens those objects do have an attribute containing the name they were defined with:
>>> def x():
... pass
...
>>> print x.__name__
x
因此,一个简单的方法可能是这样:
So, a naïve approach might be this:
>>> def x():
... print x.__name__
...
>>> x()
x
那似乎行得通.但是,由于您必须知道函数内部的x
名称才能执行此操作,因此您实际上并没有获得任何好处.您可能已经做到了:
That seems to work. However, since you had to know the name of x
inside the function in order to do that, you haven't really gained anything; you might have well just have done this:
def x():
print "x"
实际上,这比这更糟,因为__name__
属性仅指的是函数定义的名称.如果它绑定到另一个名称,它将不会像您期望的那样起作用:
In fact, though, it's worse than that, because the __name__
attribute only refers to the name the function was defined with. If it gets bound to another name, it won't behave as you expect:
>>> y = x
>>> y()
x
更糟糕的是,如果原来的名称不再存在,它将根本无法使用:
Even worse, if the original name is no longer around, it won't work at all:
>>> del x
>>> y()
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 2, in x
NameError: global name 'x' is not defined
第二个问题是您实际上可以解决的问题,尽管它并不漂亮.诀窍是编写一个装饰器,该装饰器可以将函数名称作为参数传递给它:
This second problem is one you can actually get around, although it's not pretty. The trick is to write a decorator that can pass the function's name into it as an argument:
>>> from functools import wraps
>>> def introspective(func):
... __name__ = func.__name__
... @wraps(func)
... def wrapper(*args, **kwargs):
... return func(__name__=__name__, *args, **kwargs)
... return wrapper
...
>>> @introspective
... def x(__name__):
... print __name__
...
>>> x()
x
>>> y = x
>>> y()
x
>>> del x
>>> y()
x
...尽管如您所见,您仍然只返回定义该函数的名称,而不是现在刚绑定到的函数名称.
... although as you can see, you're still only getting back the name the function was defined with, not the one it happens to be bound to right now.
在实践中,简短的(正确的)答案是不要这样做".这是Python的一个基本事实,即对象不知道它们的名称(或多个名称)绑定到-如果您认为函数需要该信息,则说明您做错了.
In practice, the short (and correct) answer is "don't do that". It's a fundamental fact of Python that objects don't know what name (or names) they're bound to - if you think your function needs that information, you're doing something wrong.
这篇关于如何在函数内部获取函数对象(Python)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!