How to define free-variable in python?

Definition of a free variable: Used, but neither global nor bound.

For example:

  1. x is not free in Code 1, because it’s a global variable.
  2. x is not free in bar() in Code 2, because it’s a bound variable.
  3. x is free in foo().

Python makes this distinction because of closures. A free variable is not defined in the current environment, i. e. collection of local variables, and is also not a global variable! Therefore it must be defined elsewhere. And this is the concept of closures. In Code 2, foo() closes on x defined in bar(). Python uses lexical scope. This means, the interpreter is able to determine the scope by just looking at the code.

For example: x is known as a variable in foo(), because foo() is enclosed by bar(), and x is bound in bar().

Global scope is treated specially by Python. It would be possible to view the global scope as an outermost scope, but this is not done because of performance (I think). Therefore it is not possible that x is both free and global.

Exemption

Life is not so simple. There exist free global variables. Python docs (Execution model) says:

The global statement has the same scope as a name binding operation in the same block. If the nearest enclosing scope for a free variable contains a global statement, the free variable is treated as a global.

>>> x = 42
>>> def foo():
...   global x
...   def baz():
...     print(x)
...     print(locals())
...   baz()
... 
>>> foo()
42
{}

I didn’t know that myself. We are all here to learn.

Leave a Comment