0

How does Python handle functions that allocate a new object and return a reference?

def fun_function():
    obj = {}
    for x in range(100):
        obj[x] = True
    return obj

Something like this would not work in C if I recall because of the stack pointer, but in Python it seems to work. Could there be memory consequences of this kind of return value for long running programs?

Is it more preferred to pass a handle to the object into the function?

jonrsharpe
  • 115,751
  • 26
  • 228
  • 437
Matt
  • 3,592
  • 5
  • 21
  • 26
  • 2
    In Python, you **always** pass by assignment (or *"pass references by value"*) - please read http://stackoverflow.com/q/986006/3001761 – jonrsharpe Mar 17 '15 at 23:55
  • If you are familiar with value, reference, and pointer semantics in `C`, then in `Python` you can think of this as returning an object *by value* – Cory Kramer Mar 17 '15 at 23:56
  • `obj` would only be a local variable, which i'm quite sure gets garbage collected when the function stops executing. – Zizouz212 Mar 17 '15 at 23:56
  • 1
    @Zizouz212 not if it's `return`ed and assigned outside the function. – jonrsharpe Mar 17 '15 at 23:57
  • 4
    @Zizouz212 -- Not true. CPython works on reference counting. While it's true that one reference goes away (the local), another reference sticks around (the one that the caller gets from the return statement) so `obj` isn't available to be garbage collected just yet. – mgilson Mar 17 '15 at 23:58
  • Ahhh... Learned something new! – Zizouz212 Mar 17 '15 at 23:59
  • 1
    It seems like everyone has a different idea of how it works. What about the Python private heap? If all objects are allocated onto the private heap why would any variable ever go out of scope in the literal sense? – Matt Mar 18 '15 at 00:10

2 Answers2

0

In Python, everything is allocated on the heap (or for the few things that aren't, you can't tell that they're not). The garbage collector will take care of freeing objects when they're no longer reachable. There is no equivalent to C's stack-based variable lifetime; you never have to worry about an object getting deallocated while you're using it.

user2357112
  • 260,549
  • 28
  • 431
  • 505
  • Python does have a garbage collector, but it is a secondary measure, and is limited (it can see through cycles but cannot free objects that implement a `__del__()` method). Python's primary memory management method is reference counting, not garbage collection. See [mgilson's comment above](http://stackoverflow.com/questions/29111858/why-can-i-return-references-to-objects#comment46452852_29111858). – Frédéric Hamidi Mar 18 '15 at 00:04
  • 1
    @FrédéricHamidi: [It can free objects with a Python-level `__del__` in newer versions, actually.](https://www.python.org/dev/peps/pep-0442/) While CPython uses reference counting, that's an implementation detail of that particular implementation's garbage collection scheme. I believe most other implementations keep no reference counts. – user2357112 Mar 18 '15 at 00:09
  • Cool, I have to read this PEP in my copious free time, it looks like the garbage collection feature has improved while I wasn't watching :) That said, garbage collection is not the same thing as reference counting at all, and none is a subset of either. Compounding them is like saying ostriches are a subset of hawks just because they're both birds. – Frédéric Hamidi Mar 18 '15 at 00:14
  • @FrédéricHamidi: I consider reference counting a (bad) form of garbage collection. I've never seen anything indicating a consensus on whether the term applies or not. – user2357112 Mar 18 '15 at 00:20
  • Well, there are several forms of garbage collection, based around the same root behavior (generational, non-generational, mark-and-sweep, stop-and-compact, etc.). None of these forms or their combinations involve reference counting. Garbage collection and reference counting are different tools made to address different purposes. Ironically, that's why Python has both :) – Frédéric Hamidi Mar 18 '15 at 00:24
-3

You basically have a factory method here. the local pointer is lost, the calling method is handed a pointer to the newly created list (obj local variable)

once the pointer outside the method is de-scoped, the memory will not be collected by the garbage collector, but it is not a memory leak unless that assignment is in global scope.

Nathan Tregillus
  • 6,006
  • 3
  • 52
  • 91
  • 1
    “once the pointer outside the method is de-scoped, the memory will not be collected by the garbage collector” – why not? If we’re talking about CPython and the “collector” is reference counting, it seems like it should. – Ry- Mar 18 '15 at 00:06
  • from my understanding, you instantiate the dictionary in the heap, then return a pointer to the calling code. maybe I am not understanding the question, but this is type of factory method is pretty standard in any language. I think the poster is over thinking this. – Nathan Tregillus Mar 19 '15 at 15:50
  • gotta love downvotes with no comment on why. – Nathan Tregillus Apr 28 '15 at 00:49
  • There is a comment up there ^ – Ry- Apr 28 '15 at 04:42