一小段代码将解释我为什么要问以及为什么这不是重复。 (我希望)
>>> def foo():
... return 1
...
>>> bar=foo
>>> bar.__name__
'foo'
如何获得'bar'?
我已经尝试过检查和帧,但到目前为止我发现的所有内容都未通过此测试。
答案 0 :(得分:2)
bar
只是对已创建对象(foo
)的引用,执行bar=foo
表示您创建了对同一对象的另一个引用。
In [62]: def foo():pass
In [63]: bar=foo
In [64]: spam=bar #another reference to foo function object
In [65]: spam.__name__,bar.__name__
Out[65]: ('foo', 'foo')
In [66]: spam is foo,bar is foo
Out[66]: (True, True)
In [67]: import sys
In [68]: sys.getrefcount(foo) # no of variable pointing to that object
Out[68]: 4 #3+1, 1 added by default by getrefcount()
答案 1 :(得分:1)
分配bar = foo
后,您有两个名称都指向完全相同的值。 Python中没有办法区分它们。 Python中的赋值永远不会复制数据,它只是使名称引用一个值,而函数是一个像任何其他值一样的值。只有一个函数,它只有一个__name__
。
答案 2 :(得分:0)
如果你知道foo
,那么你可以检查globals()
以查看是否为该功能分配了其他功能,请注意这将选择所有其他参考:
>>> function_reference_names = [k for k, v in globals().iteritems() if hasattr(globals()[k], "func_name") and globals()[k].func_name == bar.__name__ and k != bar.__name__]
>>> function_reference_names
['bar']
但正如其他人所指出的那样,如果你想这样做,你可能会提出错误的问题。
答案 3 :(得分:0)
这是一个有趣的问题,一个函数可以知道它的名字叫什么名字吗?据我所知,这条信息没有存储在堆栈或其他任何地方,所以要获取它,我们必须进入更高维度,或去meta ,来操纵源本身的信息。
结果可能没用,但很有趣:)
以下是笨拙的代码:
import inspect
import io
import re
def get_my_name(func_obj):
caller_frame = inspect.currentframe().f_back.f_back
caller_mod = inspect.getmodule(caller_frame)
mod_src = inspect.getsource(caller_mod)
call_lineno = caller_frame.f_lineno
stream = io.StringIO(mod_src)
for i in range(0, call_lineno):
line = stream.readline()
m = re.findall('[_a-zA-Z0-9]+(?=\()', line)
m = [fname for fname in m if caller_frame.f_locals[fname] == func_obj]
return m
def some_func(n):
print(get_my_name(some_func))
return n*n
def caller():
f = some_func
return f(2)
caller()