Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why doesn't Python's nonlocal keyword like the global scope?

Tags:

In Python 3.3.1, this works:

i = 76

def A():
    global i
    i += 10

print(i) # 76
A()
print(i) # 86

This also works:

def enclosing_function():
    i = 76
    def A():
        nonlocal i
        i += 10

    print(i) # 76
    A()
    print(i) # 86

enclosing_function()

But this doesn't work:

i = 76
def A():
    nonlocal i # "SyntaxError: no binding for nonlocal 'i' found"
    i += 10

print(i)
A()
print(i)

The documentation for the nonlocal keyword states (emphasis added):

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope.

In the third example, the "nearest enclosing scope" just happens to be the global scope. So why doesn't it work?

PLEASE READ THIS BIT

I do notice that the documentation goes on to state (emphasis added):

The [nonlocal] statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

but, strictly speaking, this doesn't mean that what I'm doing in the third example shouldn't work.

like image 902
qntm Avatar asked Jun 01 '13 14:06

qntm


People also ask

What is difference between global and nonlocal in Python?

An important difference between nonlocal and global is that the a nonlocal variable must have been already bound in the enclosing namespace (otherwise an syntaxError will be raised) while a global declaration in a local scope does not require the variable is pre-bound (it will create a new binding in the global ...

What does nonlocal keyword do in Python?

The nonlocal keyword is used to work with variables inside nested functions, where the variable should not belong to the inner function. Use the keyword nonlocal to declare that the variable is not local.

What is global keyword in Python?

In Python, global keyword allows you to modify the variable outside of the current scope. It is used to create a global variable and make changes to the variable in a local context.

What are nonlocal variables in Python?

In python, nonlocal variables refer to all those variables that are declared within nested functions. The local scope of a nonlocal variable is not defined. This essentially means that the variable exists neither in the local scope nor in the global scope.

What is global and nonlocal keyword in Python?

In this tutorial we will learn about global and nonlocal keyword in Python . Before going through this tutorial we need to know about namespace and scope in Python . Global keyword in Python helps us to change value of a global variable inside a function .

What is the use of nonlocal in Python?

Python nonlocal keyword is used to reference a variable in the nearest scope. In this example, we demonstrate the working of the nonlocal keyword. The nonlocal keyword won’t work on local or global variables and therefore must be used to reference variables in another scope except the global and local one.

What is the use of nonlocal keyword in C++?

The nonlocal keyword won’t work on local or global variables and therefore must be used to reference variables in another scope except the global and local one. The nonlocal keyword is used in nested functions to reference a variable in the parent function. It helps in accessing the variable in the upper scope.

How to change the value of a global variable in Python?

Global keyword in Python helps us to change value of a global variable inside a function . First we will write a program to change the value of a global variable inside a function without global keyword and check whether the program actually change the value of the global variable or not .


2 Answers

The search order for names is LEGB, i.e Local, Enclosing, Global, Builtin. So the global scope is not an enclosing scope.

EDIT

From the docs:

The nonlocal statement causes the listed identifiers to refer to previously bound variables in the nearest enclosing scope. This is important because the default behavior for binding is to search the local namespace first. The statement allows encapsulated code to rebind variables outside of the local scope besides the global (module) scope.

like image 147
Mike Müller Avatar answered Oct 08 '22 01:10

Mike Müller


why is a module's scope considered global and not an enclosing one? It's still not global to other modules (well, unless you do from module import *), is it?

If you put some name into module's namespace; it is visible in any module that uses module i.e., it is global for the whole Python process.

In general, your application should use as few mutable globals as possible. See Why globals are bad?:

  • Non-locality
  • No Access Control or Constraint Checking
  • Implicit coupling
  • Concurrency issues
  • Namespace pollution
  • Testing and Confinement

Therefore It would be bad if nonlocal allowed to create globals by accident. If you want to modify a global variable; you could use global keyword directly.

  • global is the most destructive: may affect all uses of the module anywhere in the program
  • nonlocal is less destructive: limited by the outer() function scope (the binding is checked at compile time)
  • no declaration (local variable) is the least destructive option: limited by inner() function scope

You can read about history and motivation behind nonlocal in PEP: 3104 Access to Names in Outer Scopes.

like image 42
jfs Avatar answered Oct 08 '22 03:10

jfs