Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python overwriting variables in nested functions

Tags:

python

scope

Suppose I have the following python code:

def outer():     string = ""     def inner():         string = "String was changed by a nested function!"     inner()     return string 

I want a call to outer() to return "String was changed by a nested function!", but I get "". I conclude that Python thinks that the line string = "string was changed by a nested function!" is a declaration of a new variable local to inner(). My question is: how do I tell Python that it should use the outer() string? I can't use the global keyword, because the string isn't global, it just lives in an outer scope. Ideas?

like image 926
Ord Avatar asked Oct 28 '11 23:10

Ord


People also ask

Are nested functions Pythonic?

Inner functions, also known as nested functions, are functions that you define inside other functions. In Python, this kind of function has direct access to variables and names defined in the enclosing function.

Does Python have nested subprograms?

So, in Python, nested functions have direct access to the variables and names that you define in the enclosing function. It provides a mechanism for encapsulating functions, creating helper solutions, and implementing closures and decorators.

Are closures Pythonic?

Closures are elegant Python constructs. In this article, we'll learn about them, how to define a closure, why and when to use them. But before getting into what a closure is, we have to first understand what a nested function is and how scoping rules work for them.


1 Answers

In Python 3.x, you can use the nonlocal keyword:

def outer():     string = ""     def inner():         nonlocal string         string = "String was changed by a nested function!"     inner()     return string 

In Python 2.x, you could use a list with a single element and overwrite that single element:

def outer():     string = [""]     def inner():         string[0] = "String was changed by a nested function!"     inner()     return string[0] 
like image 145
Sven Marnach Avatar answered Sep 17 '22 10:09

Sven Marnach