2

一小段代码将解释我为什么要问以及为什么这不是重复的。(我希望)

>>> def foo():
...    return 1
... 
>>> bar=foo
>>> bar.__name__
'foo'

我如何获得“酒吧”?

我试过检查和框架,但到目前为止我发现的所有东西都没有通过这个测试。

4

4 回答 4

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()
于 2013-01-25T01:02:57.333 回答
1

分配后bar = foo,您有两个名称都引用完全相同的值。Python 没有办法区分它们。Python 中的赋值从不复制数据,它只是让名称引用一个值,而函数就像其他任何值一样是一个值。只有一个功能,它只有一个__name__

于 2013-01-25T00:42:56.347 回答
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']

但正如其他人指出的那样,如果你想这样做,你可能会问错问题。

于 2013-01-25T01:09:06.577 回答
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()
于 2013-01-25T10:41:54.563 回答