想象一下我有:
X = [0,1]
Y = X
Z = Y
是否有像 referenced_by(X) 这样的函数返回类似的东西['Y', 'Z']
?还有一个像 points_to(Y) 这样返回的函数'X'
?
我知道is
要测试对象是否相同,但我只是想要一种快速获取名称的方法。
是的,没有。您可以获得全局变量列表:
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']
但是由于您不知道变量a
、b
和是在哪个上下文c
中obj
定义的,所以它又一次非常无用。例如,将 a 的定义移动到模块级别,您会得到以下结果:
['c', 'b', 'a', 'obj', 'a', 'a']
其中之一a
是全局的,而其他的则是本地环境的副本。
至于你的第二个问题:
还有一个像 points_to(Y) 这样返回“X”的函数?
那是相同的功能。两者X
和Y
都只是指向同一个对象的名称,在这种情况下是一个列表。X
与 没有区别Y
,Y
也不指向X
。Y
指向[0,1]
等等X
。