11

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.

4
  • Why? Why do you want this? What possible purposes can it serve? Commented Dec 3, 2010 at 4:04
  • 2
    Now you only repeated /what/ you want, not /why/ you want it. Commented Dec 3, 2010 at 17:18
  • The reason b and c are not altered when you change the value of a is because the int type is immutable. You'd need a simple container before you could do it like that. Commented Dec 3, 2010 at 23:21
  • 1
    @ChrisMorgan: It's not because int is immutable. If those were objects, you'd still have the same effect. a is being reassigned to something different, but b and c aren't touched. If a was an object and you modified a property of a, then the other 2 would be updated as well. Commented Jul 1, 2012 at 18:53

7 Answers 7

11

As you can see, it's impossible to find them all.

>>> sys.getrefcount(1)
791
>>> sys.getrefcount(2)
267
>>> sys.getrefcount(3)
98
Sign up to request clarification or add additional context in comments.

Comments

10

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

Comments

5

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/

Comments

3

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.

2 Comments

I think your answer is factually wrong, considering that objgraph does exactly that—find references to a given object.
@ErikAllik This is possible only in some Python implementations, because it relies on non-portable features of the GC. For example, it will not work in Jython. I'll mention it in the answer, though.
2

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']

3 Comments

thanks, that is one approach, but that has no means for me in semantic, my question is I try to express the "variable" a, b, c is a "ref" of the value 1, they are same reference of value 1, but if I define another d = 1, there's no doubt id(d) is same as id(a), but here I think it has the mean of d.value = a.value but not means d = a although they DO tag same object in python I known.
@user478514: that's demonstrating slightly that it can't be done.
@user478514: The fact that "a = 1; d = 1; id(a) == id(d) -> True" is a coincidence. As an optimization, python has an internal list of all integers from -5 to 256: any reference to one of those integers gets a reference to the one from this internal list. If you try the same test in general, with another class or even an integer greater than 256, you'll find that this returns False. E.g. a = 300; d = 300; id(a) == id(d) -> False
1

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.

Comments

0

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.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.