Issue 4921: Object lifetime and inner recursive function
Created on 2009-01-12 11:19 by ocean-city, last changed 2022-04-11 14:56 by admin. This issue is now closed.
| Files | ||||
|---|---|---|---|---|
| File name | Uploaded | Description | Edit | |
| q112.py | ocean-city, 2009-01-12 15:08 | |||
| Messages (7) | |||
|---|---|---|---|
| msg79664 - (view) | Author: Hirokazu Yamamoto (ocean-city) * ![]() |
Date: 2009-01-12 11:19 | |
Hello. Sorry if this is noise. I expected
__del__
out of function
__del__
out of function
__del__
out of function
on following code, but actually I got
out of function
out of function
out of function
__del__
__del__
__del__
Is this expected behavoir? (I believed `a' would be
freed after returned from f(), so I was suprised)
If I remove the comment of gc.collect(), the code works as expected.
///////////////////////////////
import gc
class A:
def __del__(self):
print("__del__")
def f():
a = A()
def g():
a
g()
def main():
for _ in range(3):
f()
# gc.collect()
print("out of function")
if __name__ == '__main__':
main()
|
|||
| msg79670 - (view) | Author: Antoine Pitrou (pitrou) * ![]() |
Date: 2009-01-12 12:21 | |
Since g calls "itself" in its own scope, it is stored as one of its own
cell vars, which creates a reference cycle. a is also part of its
reference cycle for the same reason, so it must wait for garbage
collection to be reclaimed.
If g didn't keep a reference to its cell vars, closures wouldn't be
possible, because the cell vars wouldn't survive the end of f's scope.
(g doesn't have to be recursive, it's enough that it makes a reference
to itself in its own scope:
def f():
a = A()
def g():
a
g
or even:
def f():
a = A()
def g():
a
h
h = g
)
|
|||
| msg79672 - (view) | Author: Hirokazu Yamamoto (ocean-city) * ![]() |
Date: 2009-01-12 12:58 | |
Thank you for explanation. The combination of inner function + method variable was very handy for me, but maybe I should refrain from using it lightly. :-( |
|||
| msg79680 - (view) | Author: Hirokazu Yamamoto (ocean-city) * ![]() |
Date: 2009-01-12 15:08 | |
A little followup. Attached script q112.py (some puzzle program) ate up my RAM (80MB) and never ran GC while solving. Current python GC looks at the number of GC objects, but GC object like set object can contain many non GC object, so... I feel it would be nice if there is better GC triger/timing. |
|||
| msg79706 - (view) | Author: Antoine Pitrou (pitrou) * ![]() |
Date: 2009-01-12 22:51 | |
Well, tracking memory consumption of each container would be better than simpling couting them, but it's much more complicated as well (not to mention that memory consumption can vary, so you must recalculate it periodically...). |
|||
| msg312343 - (view) | Author: Eric Wieser (Eric.Wieser) * | Date: 2018-02-19 08:33 | |
Would it be possible for function self-reference cell vars to be weak references? This wouldn't solve the issue for co-recursive inner functions, but would at least prevent reference cycles for the more common case of simple recursive functions. |
|||
| msg324987 - (view) | Author: Eric Wieser (Eric.Wieser) * | Date: 2018-09-11 05:09 | |
For anyone doing archaeology - this came up on python-dev about a year after this issue was filed: https://mail.python.org/pipermail/python-dev/2009-December/094439.html |
|||
| History | |||
|---|---|---|---|
| Date | User | Action | Args |
| 2022-04-11 14:56:44 | admin | set | github: 49171 |
| 2018-09-11 14:43:05 | eric.snow | set | nosy:
+ eric.snow |
| 2018-09-11 05:09:24 | Eric.Wieser | set | messages: + msg324987 |
| 2018-02-19 08:33:42 | Eric.Wieser | set | nosy:
+ Eric.Wieser messages: + msg312343 |
| 2009-01-12 22:51:35 | pitrou | set | messages: + msg79706 |
| 2009-01-12 15:08:24 | ocean-city | set | files:
+ q112.py messages: + msg79680 |
| 2009-01-12 12:58:16 | ocean-city | set | status: open -> closed resolution: not a bug messages: + msg79672 |
| 2009-01-12 12:21:41 | pitrou | set | nosy:
+ pitrou messages: + msg79670 |
| 2009-01-12 11:19:17 | ocean-city | create | |
