Retrieving the list of references to an object in Python
All:
a = 1
b = 开发者_开发百科a
c = b
Now I want to get a list of object 1
tagged, which is [a, b, c]
. How could I do this?
BTW, how to call variable "a" here officially? I know so far it is a "object tag" for the object, but I have no idea what is the term of it.
Thanks!
why do I need this:
a = b = c = 1
print a, b, c
1 1 1
a = 2
print a, b, c
2 1 1
in other language such as C, a,b,c should be 2 if I re-assign a = 2, but in python, there's no such thing like reference, so the only way to change all the value of a b c is a = b = c = 2 so far as I know, that is why purposed to get all reference of an object.
As you can see, it's impossible to find them all.
>>> sys.getrefcount(1)
791
>>> sys.getrefcount(2)
267
>>> sys.getrefcount(3)
98
I'd like to clarify some misinformation here. This doesn't really have anything to do with the fact that "ints are immutable". When you write a = 2
you are assigning a
and a
alone to something different -- it has no effect on b
and c
.
If you were to modify a property of a
however, then it would effect b
and c
. Hopefully this example better illustrates what I'm talking about:
>>> 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
I think you might be interested in objgraph
. It allows you to traverse the object graph in memory, or dump a PNG
of your object graph. It's useful for debugging memory leaks.
See this page: http://mg.pov.lt/objgraph/
It is not possible to find all references to a given object in Python. It is not even possible to find all objects or all references in Python. (The CPython function gc.get_objects
does this, but it is not portable across Python implementations.)
You can use dir()
or locals()
to find all variables that exist at some scope in the program. But if objects have been defined in other places, you could miss them with this method.
What you're asking isn't very practical and isn't possible. Here's one crazy way of doing it:
>>> 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']
First of all in C, "=" is a value assignment and does not create a reference. More specifically when you write a=b=1 what happens is this.
(1) b=1 gets evaluated, assigns 1 to b and then returns 1, so the expression becomes a=1
(2) a=1 gets evaluated, assigns 1 to b and then returns 1 which is not used anywhere.
Then a=1 changes only a as expected.
In python things are a bit more complicated as every variable is a reference, but it treats numbers differently because they are immutable. In short when you write a=1 and b=1, then a is b returns True. But changing one will not change the other.
This however does not happen with objects, with them a reference works as expected. So if you want to do what you describe maybe you should define a new object that holds the value you want and assign this to a variable.
Look at pyjack. Its replace_all_refs function seems to work pretty well to replace all references to an object. Note: Doesn't work well with string objects.
精彩评论