Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Keyword which are not often used: global vs nonlocal #34

Open
selfboot opened this issue Jun 24, 2017 · 0 comments
Open

Keyword which are not often used: global vs nonlocal #34

selfboot opened this issue Jun 24, 2017 · 0 comments

Comments

@selfboot
Copy link
Owner

global

The global statement is a declaration which holds for the entire current code block. It means that the listed identifiers are to be interpreted as globals. While using global names is automatic if they are not defined in the local scope, assigning to global names would be impossible without global.

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).

Look at the demo:

a = 0
b = 1
def func():
    print a
    print b
    b = 4

func()

With the statement b = 4 commented out, this code outputs 0 1, just what you'd expect. But if you uncomment that line, on the line print b, you get the error UnboundLocalError: local variable 'b' referenced before assignment.

This is because during static analysis, the interpreter determines that b is assigned to in func, and that it is therefore a local variable of inner. The print line attempts to print the b in that func scope before it has been assigned.

We can use global b to declare that b is the global variable.

a = 0
b = 1
def func():
    global b
    print a
    print b
    b = 4

func()

nonlocal

Global is not enough actually, suppose I have the following python code:

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

print outer()

It will print enclosed. What if I want the string in function outer to be changed within nested function inner. Add 'global string' can't work, this will modify the global variable. In Python 3.x, you can use the nonlocal keyword:

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

print(outer())

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.

Ref
#33
Python Scopes and Namespaces
Python overwriting variables in nested functions
Using global variables in a function other than the one that created them

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

1 participant