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

前端 未结 4 1294
一生所求
一生所求 2021-02-01 21:08

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 en         


        
相关标签:
4条回答
  • 2021-02-01 21:14

    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.

    0 讨论(0)
  • 2021-02-01 21:27

    It depends upon the Boundary cases:

    nonlocals come with some senstivity areas which we need to be aware of. First, unlike the global statement, nonlocal names really must have previous been assigned in an enclosing def's scope when a nonlocal is evaluated or else you'll get an error-you cannot create them dynamically by assigning them anew in the enclosing scope. In fact, they are checked at function definition time before either or nested function is called

    >>>def tester(start):
          def nested(label):
             nonlocal state   #nonlocals must already exist in enclosing def!
             state = 0
             print(label, state)
          return nested
    SyntaxError: no binding for nonlocal 'state' found
    
    >>>def tester(start):
          def nested(label):
              global state   #Globals dont have to exits yet when declared
              state = 0      #This creates the name in the module now
              print(label, state)
          return nested
    
    >>> F = tester(0)
    >>> F('abc')
    abc 0
    >>> state
    0
    

    Second, nonlocal restricts the scope lookup to just enclosing defs; nonlocals are not looked up in the enclosing module's global scope or the built-in scope outside all def's, even if they are already there:

    for example:-

    >>>spam = 99
    >>>def tester():
          def nested():
             nonlocal spam  #Must be in a def, not the module!
             print('current=', spam)
             spam += 1
          return nested
    SyntaxError: no binding for nonlocal 'spam' found
    

    These restrictions make sense once you realize that python would not otherwise generally know enclosing scope to create a brand-new name in. In the prior listing, should spam be assigned in tester, or the module outside? Because this is ambiguous, Python must resolve nonlocals at function creation time, not function call time.

    0 讨论(0)
  • 2021-02-01 21:31

    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.

    0 讨论(0)
  • 2021-02-01 21:31

    The answer is that the global scope does not enclose anything - it is global to everything. Use the global keyword in such a case.

    0 讨论(0)
提交回复
热议问题