osdir.com


[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Design: method in class or general function?


Leam Hall wrote:

> I do not understand your last sentence about reference cycle. 

Currently you have

- create Career instance which stores character as an attribute
- make modifications to character
- forget about Career instance

My suggestion

- create Career instance which stores character as an attribute
- make modifications to character, among those
- enter career into the character.careers dict

Then the cycle goes

character --> careers dict --> career instance --> character

Such a cycle isn't too bad, I just thought I'd mention it for the gallery ;)
It means that reference count will never go to 0:

>>> class A:
...    def __del__(self): print("A says bye!")
... 
>>> class B:
...    def __del__(self): print("B says bye!")
... 

Case 1, a --> b, no cycle:

>>> a = A(); a.b = B()
>>> del a
A says bye!
B says bye!

Case 2, a --> b --> a, reference cycle:

>>> a = A(); a.b = B(); a.b.a = a
>>> del a

At that point we can neither access a nor b, but as a holds a reference to b 
and b holds a reference to a the reference count of both stays above 0 and 
they live forever after -- or until the garbage collector kicks in.
Triggering it manually, for demonstration purposes:

>>> import gc; gc.collect()
A says bye!
B says bye!
4

That's for Python 3, in Python 2 the output will be

>>> import gc; gc.collect()
4

The objects will still be released, it's only that you don't see it because 
their __del__() methods aren't invoked.