全部:
a = 1
b = a
c = b
现在我想获取标记为
1
的对象列表,即 [a, b, c]
。我怎么能做到这一点?
顺便说一句,这里如何正式调用变量“a”?到目前为止我知道它是该对象的“对象标签”,但我不知道它的术语是什么。
谢谢!
为什么我需要这个:
a = b = c = 1
print a, b, c
1 1 1
a = 2
print a, b, c
2 1 1
在其他语言中,例如C,如果我重新分配a = 2,a,b,c应该是2,但在python中,没有像引用这样的东西,所以改变a b c的所有值的唯一方法是a =据我所知,b = c = 2,这就是为什么要获取对象的所有引用。
如您所见,不可能全部找到它们。
>>> sys.getrefcount(1)
791
>>> sys.getrefcount(2)
267
>>> sys.getrefcount(3)
98
我想澄清一些错误信息。这实际上与“整数是不可变的”这一事实没有任何关系。当您写
a = 2
时,您将 a
和 a
单独分配给不同的东西 - 它对 b
和 c
没有影响。
如果您要修改 a
的
属性,那么它会影响
b
和 c
。希望这个例子能更好地说明我正在谈论的内容:
>>> a = b = c = [1] # assign everyone to the same object
>>> a, b, c
([1], [1], [1])
>>> a[0] = 2 # modify a member of a
>>> a, b, c
([2], [2], [2]) # everyone gets updated because they all refer to the same object
>>> a = [3] # assign a to a new object
>>> a, b, c
([3], [2], [2]) # b and c are not affected
在 Python 中不可能找到对给定对象的所有引用。在 Python 中甚至不可能找到所有对象或所有引用。 (CPython 函数
gc.get_objects
可以执行此操作,但它不可跨 Python 实现移植。)
您可以使用
dir()
或 locals()
查找程序中某个范围内存在的所有变量。但如果对象已在其他地方定义,则使用此方法可能会错过它们。
你所要求的不太实际,也是不可能的。这是一种疯狂的做法:
>>> a = 1
>>> b = a
>>> c = b
>>> locals()
{'a': 1, 'c': 1, 'b': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
>>> [key for key, value in locals().items() if value == 1]
['a', 'c', 'b']
>>> globals()
{'a': 1, 'c': 1, 'b': 1, '__builtins__': <module '__builtin__' (built-in)>, '__package__': None, '__name__': '__main__', '__doc__': None}
>>> [key for key, value in globals().items() if value == 1]
['a', 'c', 'b']
首先在C中,“=”是赋值,并不创建引用。更具体地说,当你写 a=b=1 时,会发生这样的情况。
(1) b=1 被求值,将 1 赋给 b,然后返回 1,因此表达式变为 a=1
(2) a=1 被求值,将 1 赋给 b,然后返回 1,该值在任何地方都没有使用。
然后 a=1 按预期仅更改 a。
在Python中,事情有点复杂,因为每个变量都是一个引用,但它对待数字的方式不同,因为它们是不可变的。简而言之,当你写a=1和b=1时,那么a is b返回True。但改变其中之一并不会改变另一个。
然而,对于对象来说,这种情况不会发生,对于它们来说,引用会按预期工作。因此,如果您想做您所描述的事情,也许您应该定义一个新对象来保存您想要的值并将其分配给一个变量。
看看pyjack。它的replace_all_refs函数似乎可以很好地替换对对象的所有引用。注意:不适用于字符串对象。
我写了一个小库来帮助解决这个问题:https://github.com/nfergu/referrers。
它有助于回答“什么持有对该对象的引用?”的问题。通过尝试为对象的每个引用分配一个有意义的名称并返回引用图(包括间接引用)。