0

I've learned that, for optimization reasons, Python's inner functions do not actually have a pointer to their parent frame but they store the parent variables in a special object called "cell" (func.func_closure)

I've figured that those vars are been copied to that cell, so if it's true I cannot use setters and getters as inner functions because each of them has a copy of the variable.

In order to test that theory I've written the following code:

def foo(x):
    def getter():
            x
    def setter(y):
            x=y
    def adder(y):
            if isinstance(y, list):
                    x += y
            else:
                    print "not a list"
    return (getter, setter, adder)

But when I ran it I found something even more odd: its seems that only the function getter saves its parent's (foo) variables, although I would think that setter and adder should also save it.

I tested it using Python 2.7 and found out that after calling

(g,s,a) = foo([1])

g.func_code.co_freevars  # contains ('x',)
s.func_code.co_freevars  # is empty
a.func_code.co_freevars  # also empty

Does anyone know why that is?

Martijn Pieters
  • 1,048,767
  • 296
  • 4,058
  • 3,343
doroninou
  • 13
  • 2
  • You have assignments to `x` in both `setter` and `adder`, so it's a local name not a closed-over "free variable". This is the same sort of thing that causes `UnboundLocalError `s. – jonrsharpe Jul 05 '16 at 09:58
  • Also please read tags before adding them: *"This tag is in the process of removal (http://meta.stackoverflow.com/questions/251723/remove-implementation). Please don't use it."* – jonrsharpe Jul 05 '16 at 10:00
  • thanks @jonrsharpe, so how could i tell python i want to use the parent's x var ? – doroninou Jul 05 '16 at 11:44
  • In 3.x, [`nonlocal`](https://www.python.org/dev/peps/pep-3104/), but there's probably a better way to solve whatever your actual problem is. – jonrsharpe Jul 05 '16 at 11:46

0 Answers0