Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Local functions in Python

In the following Python code, I get an UnboundLocalError. As I understand it, local functions share the local variables of the containing function, but this hardly seems to be the case here. I recognise that a is an immutable value in this context, but that should not be a problem.

def outer():     a = 0     def inner():         a += 1     inner() outer() 

It would seem that the inner function has received copies of all the references in the parent function, as I do not get the UnboundLocalError exception if the value of a is wrapped in a mutable type.

Is someone able to clarify the behaviour here, and point me to the appropriate Python documentation on this?

like image 372
Matt Joiner Avatar asked Sep 12 '09 04:09

Matt Joiner


People also ask

What is a local function in Python?

In Python or any other programming languages, the definition of local variables remains the same, which is “A variable declared inside the function is called local function”. We can access a local variable inside but not outside the function.

What is local and global function in Python?

If you create a variable with the same name inside a function, this variable will be local, and can only be used inside the function. The global variable with the same name will remain as it was, global and with the original value.

What are the 4 types of functions in Python?

Moreover, we will study the different types of functions in Python: Python built-in functions, Python recursion function, Python lambda function, and Python user-defined functions with their syntax and examples.

How do you access a local function in Python?

Python | locals() function Local symbol Table: This symbol table stores all information needed for the local scope of the program and this information is accessed using python built-in function locals().

What is locals() function in Python?

Python locals () function returns the dictionary of the current local symbol table. Symbol table: It is a data structure created by a compiler for which is used to store all information needed to execute a program.

What is a local variable in Python?

Local variables are those which are initialized inside a function and belongs only to that particular function. It cannot be accessed anywhere outside the function. Let’s see how to create a local variable. Attention geek! Strengthen your foundations with the Python Programming Foundation Course and learn the basics.

How to use local symbol table in Python?

Local symbol Table: This symbol table stores all information needed for the local scope of the program and this information is accessed using python built-in function locals (). Parameters: This function does not takes any input parameter. Return Type : This returns the information stored in local symbol table.

What is the difference between locals() and globals() in Python?

The locals () is an inbuilt function in Python that returns the dictionary of the current local module namespace. In other words, this function returns all necessary information about the local scope of the program including the variable names, methods, etc. However, at the module level, locals () and globals () are the same dictionaries.


2 Answers

I believe you're correct in seeing this as a "mutability" problem. While the code you posted does throw an "UnboundLocalError", the following code does not:

def outer():     a = 0     def inner():         print a     inner() outer() 

Python doesn't allow you to reassign the value of a variable from an outer scope in an inner scope (unless you're using the keyword "global", which doesn't apply in this case).

Check out the bottom section of the "classes" documentation in this Python 2.6.2 documentation:

9.2. Python Scopes and Namespaces

[…] If a name is declared global, then all references and assignments go directly to the middle scope containing the module’s global names. Otherwise, all variables found outside of the innermost scope are read-only (an attempt to write to such a variable will simply create a new local variable in the innermost scope, leaving the identically named outer variable unchanged).

Your "UnboundLocalError" is because your function is actually declaring a new variable called "a" and then immediately trying to do a "+=" operation on it, but this fails because "a" does not have a value yet. (View the "a+=1" as "a = a+1" and you can see the problem if "a" is undefined).

In general, if you're going to want to modify "a", the way people usually get around it is to use a mutable type to pass "a" around (such as a list or a dictionary). You can modify "a" via the contents of the mutable type (as you probably noticed in your testing with this setup).

Hope that helps!

like image 151
Brent Writes Code Avatar answered Oct 15 '22 21:10

Brent Writes Code


You should specify your variable as nonlocal to preserve it's state in closure, so definition should be like this

def outer():     a = 0     def inner():         nonlocal a         a += 1     inner() 
like image 24
vaduha Avatar answered Oct 15 '22 21:10

vaduha