I am using the with
block to extract information from a file, and I am surprised that any variables declared in the with
block are global. Shouldn't they be local to the with
block, and shouldn't you need to use global myVar
before changing global variables? After all, with
defines a code block, right?
Python doesn't have block scopes. The with
statement does not introduce a new scope; the body of the statement is still in the same scope that has the with
statement.
Python has 4 kinds of scopes:
import
. No other construct defines a new scope: not if
statements, not for
or while
loops, not with
statements, not try
statements, not class
statements. Only things that define new functions ( def
statements, lambda expressions, and comprehensions) create new (local) scopes.
Every name first looks in the local scope (which may be the global scope if not inside a function definition), then in any non-local scopes (which may not exist, if a function is defined in the global scope, not another local scope), then the global scope, and finally in the built-in scope.
A non-local scope is just a scope that isn't the current local scope. For a module defined at the global scope, the closest enclosing non-local scope is the global scope.
But if a function is defined inside another function, then the closest enclosing non-local scope is the local scope in which the function is defined.
Functions can be nested fairly deeply, so there could be 0 or more additional local scopes between the current local scope and the global scope in which name lookups can occur. For example,
x1 = 'a'
def f1():
x2 = 'b'
def f2():
x3 = 'c'
def f3():
x4 = 'd'
print(x1 + x2 + x3 + x4)
f3()
f2()
f1()
The output of this mess would be abcd
. When the argument to the print
statement requires values for each of the four variables, each lookup starts in the local scope. Only a value for x4
is found there; the other lookups extend into the nearest enclosing non-local scope, that of f2
. A value for x3
is found there, so the lookup for x1
and x2
extend to the next non-local scope, that of f1
. x2
is found, so f1
extends another stop. Finally, a value for x1
is found in the global scope.
So a non-local scope isn't so much a special kind of scope, just a name for a scope that isn't local to the currently executing function. It will either be the local scope of an enclosing function or the global scope.
A with
statement does not create a scope (like if, for and while
do not create a scope either).
As a result, Python will analyze the code and see that you made an assignment in the with statement, and thus that will make the variable assignment.
Initialization before the with
scope can be safer in the sense that after the with statement we can safely assume that the variable exists. If on the other hand the variable should be assigned in the with statement, not initializing it before the with statement actually results in an additional check: Python will error if somehow the assignment was skipped in the with statement.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.