Variable scope (scope) is an easy place to drop holes in python.
There are 4 scopes in Python, namely:
- L (local) local scope
- In functions outside of the E (enclosing) closure function
- G (Global) scope
- B (built-in) built-in scopes
To l–> e–> g–>b rules to find, that is: in the local can not find, will go to local outside the local search (such as closures), and can not find the overall look, and then to the built-in search.
In addition def/class/lambda
to Python, other things if/elif/else/ try/except for/while
like: Cannot change its scope. Variables defined within them can be accessed externally.
>>> ifTrue:... ‘I am A‘... >>> a‘I am A‘# 定义在if语言中的变量a,外部还是可以访问的。# 但是需要注意如果if被 def/class/lambda 包裹,在内部赋值,就变成了此 函数/类/lambda 的局部作用域。
is def/class/lambda
assigned within, it becomes its local scope, and the local scope overrides the global scope, but does not affect the global scope.
1 #全局的def fun(): 2#局部的 return gprint fun()# 结果为2print g# 结果为1
However, it is important to note that sometimes you want to refer to global variables inside a function, and errors occur when you neglect them, such as:
#file1. py var = Span class= "Hljs-number" >1 def fun () : print var var = 200 print Fun () # file2.py var = 1 def fun () : var = var + 1 return varprint Fun () Span class= "Hljs-comment" ># both functions will be error unboundlocalerror:local variable ' var ' referenced before assignment
The error that was referenced before the value was assigned! Why? Because in the inside of the function, the interpreter detects that Var is being re-assigned, so VAR becomes a local variable, but the error occurs when you want to use Var before it is assigned. The workaround is to add the global var that is added inside the function globals var
but after the function is run.
Closed Bag closure
Closure definition: If a reference is made to a variable within an external function (but not at the global scope ) in an intrinsic function, then the intrinsic function is considered a closure (closure)
Scopes in function nesting/closures:
a = 1 def external () : global a A = 200 print a b = 100 def internal () : # nonlocal b print b b = 200 return b Internal () print bprint external ()
/ pre>
Same error-The PYTHON3 has a keyword to solve the problem before the reference is assigned , nonlocal
but do not attempt to modify the variables in the closure in Python2.
There is also a hole in the closure:
fromFunctoolsImportWraps def wrapper(log): def external(F): @wraps (F) def internal(**kw): if False: Log =' modified ' PrintLogreturnInternalreturnExternal@wrapper (' first ') def ABC(): PassPrintABC ()
There will also be a reference to the error before the assignment , because the interpreter detected the if False
re-assignment in, so it will not go to the closure of the external function (enclosing) to find the variable, but does not have to be if Flase
executed, so this error occurs. Unless you need to else: log=‘var‘
if True
, or add logical statements like this, it doesn't make sense, so try not to modify the variables in the closures.
It seems that it is not possible to implement the function of the counter in the usual way, because there count +=1
will be errors in the reference before the assignment , the workaround: (or keywords in the PY3 environment nonlocal
)
def counter(start):Count =[start] def internal():count[0] +=1 returncount[0]returnInternalcount = Counter (0) forNinchRangeTen):PrintCount ()# 1,2,3,4,5,6,7,8,9,10Count = Counter (0)PrintCount ()# 1
Because of list
the variability, strings are immutable types.
Locals () and Globals () Globals ()
global
And globals()
is different, global
is the keyword used to declare a local variable as a global variable. globals()
and locals()
provides a way for dictionary-based access to global and local variables
For example: If you need to define a local variable within function 1, the name of the other function 2 is the same, but also in function 1 to refer to the function 2.
def var(): passdef f2(): ‘Just a String‘ f1 = globals()[‘var‘] print var return type(f1)print f2()# Just a String# <type ‘function‘>
Locals ()
If you have used a Python web framework, you have experienced the need to pass a lot of local variables in a view function to the template engine, and then work on the HTML. While you can have some more clever practices, you still want to pass a lot of variables at once. You don't have to know how these grammars come about, what you do, you just need to get a general idea of what locals () is.
As you can see, locals () throws all the local variables together.
@app.route(‘/‘)def view(): user = User.query.all() article = Article.query.all() ip = request.environ.get(‘HTTP_X_REAL_IP‘, request.remote_addr) ‘Just a String‘ return render_template(‘index.html‘, user=user, article = article, ip=ip, s=s) #或者 return render_template(‘index.html‘, **locals())
Python variable Scope