4

想象一下我有:

X = [0,1]
Y = X
Z = Y

是否有像 referenced_by(X) 这样的函数返回类似的东西['Y', 'Z']?还有一个像 points_to(Y) 这样返回的函数'X'

我知道is要测试对象是否相同,但我只是想要一种快速获取名称的方法。

4

1 回答 1

2

是的,没有。您可以获得全局变量列表:

for name, val in globals().items():
    if val is obj:
        yield name

您还可以获得局部变量列表:

for name, val in locals().items():
    if val is obj:
        yield name

但是,您将错过其他上下文中的所有变量,而不是函数的本地变量或模块的全局变量。例如,您可以使用 frame-magic 在调用上下文中找到变量,但您将无法找到其他模块的全局变量。

你会用这个做什么,我不知道。

您也不会找到任何引用该对象的属性,但属性不是变量,所以也许没关系。

您可以获取所有引用您的对象的对象。这将包括所有函数的全局变量和局部变量。但在这种情况下,您无法获得变量的名称。你可以做

>>> import gc
>>> gc.get_referrers(obj)

获取引用该对象的所有对象的列表obj。再一次,这是非常没用的。:-)

如果您想要名称,您可以在引用者是字典或堆栈框架的情况下查找键:

import gc
import types

def find_ref_names(obj):
    for ref in gc.get_referrers(obj):
        if isinstance(ref, types.FrameType):
            look_in = [ref.f_locals, ref.f_globals]
        elif isinstance(ref, dict):
            look_in = [ref]
        else:
            continue
        for d in look_in:
            for k, v in d.items():
                if v is obj:
                    yield k


def main():
    a = "heybaberiba"
    b = a
    c = b

    print list(find_ref_names(b))

if __name__ == '__main__':
    main()

这将打印:

['a', 'c', 'b', 'obj']

但是由于您不知道变量ab和是在哪个上下文cobj定义的,所以它又一次非常无用。例如,将 a 的定义移动到模块级别,您会得到以下结果:

['c', 'b', 'a', 'obj', 'a', 'a']

其中之一a是全局的,而其他的则是本地环境的副本。

至于你的第二个问题:

还有一个像 points_to(Y) 这样返回“X”的函数?

那是相同的功能。两者XY都只是指向同一个对象的名称,在这种情况下是一个列表。X与 没有区别YY也不指向XY指向[0,1]等等X

于 2013-07-11T09:48:46.160 回答