Tuesday, March 1, 2011

Python initialization and circular reference counts

Can we initialize python objects with statement like this:

a = b = c = None

it seems to me when I did a = b = c = list() will cause circular reference count issue.

Please give your expert advice.

From stackoverflow
  • No. That's equivalent to:

    c = list()
    b = c
    a = b
    

    There is no problem. Why did you think there would be an issue?

    eric : Doing a = b = c = list() will make all three variables refer to the same list, isn't it? see following: a = b = c = list() b.append('x') print a, id(a) print b, id(b) print c, id(c) // the above code verifies they are refering to the same object. del a print b print c // how come b and c still exists? Didn't the list be deleted already? What is the problem here? Did I created three different lists by doing the above initialization?
    Paul McGuire : No you created 3 different references to the same list. The list exists until all 3 references have been deleted.
    eric : thanks, that makes sense.
    wescpy : specifically, it's a *reference count*. when you made the list and assigned it to 'c', the ref count is set to 1, when you similarly assigned 'a' and 'b' to it, each one represents another increment, so it's then at 3. 'del a' decrements the count down to 2... it won't get flagged for GC until it's zero.
  • There are no cycles in your corde and even if there were, python's garbage collector can handle circular reference fine, so you don't ever need to worry about that.

    However your code has another (possible) problem: All three variables will point to the same list. This means that changing e.g. a, will also change b and c (where by "changing" I mean calling a mutating operation like e.g. append. Reassigning a variable will not affect the other variables).

    Ivo Wetzel : +1 For pointing out that the names(what I think of as a better description of pythons "variables") reference to the same list.
    eric : My experience with python being automatically gc'ed is not so pleasant. Python seems allocating memory and sub-allocating as it needs. But even if it is done with the allocated memory, it doesn't seem to release freed memory to the kernel, it just holds it for future usage. I've seen it couple times at my work place, not sure if there is other memory leak issue though.
  • Yes, you can do that. There is no circular reference in your code and even if there were, it wouldn't cause any problems as Python has a garbage collector that correctly handles cycles.

0 comments:

Post a Comment