Home  >  Article  >  Backend Development  >  Comprehensive analysis of the scope of variables in Python starting from local variables and global variables

Comprehensive analysis of the scope of variables in Python starting from local variables and global variables

不言
不言Original
2018-04-27 15:31:151539browse

Whether it is class-based object-oriented programming or the definition of variables within a simple function, the scope of variables is always a link that must be understood and mastered in Python learning. Let's start with a comprehensive analysis of Python starting with local variables and global variables. For the scope of variables, friends who need it can refer to

Understanding global variables and local variables
1. If the variable name inside the defined function appears for the first time, and Before the = symbol, it can be considered to be defined as a local variable. In this case, regardless of whether the variable name is used in the global variable, the local variable is used in the function. For example:

  num = 100
  def func():
    num = 123
    print num
  func()

The output result is 123. Explain that the variable name num defined in the function is a local variable and covers the global variable. Another example:

  num = 100
  def func():
    num += 100
    print num
  func()

The output result is: UnboundLocalError: local variable 'num' referenced before assignment. Error message: Local variable num is applied before assignment. In other words, the variable is used incorrectly without being defined. This once again proves that what is defined here is a local variable, not a global variable.

2. If the variable name inside the function appears for the first time, appears after the = symbol, and has been defined as a global variable before, the global variable will be referenced here. For example:

  num = 100
  def func():
    x = num + 100
    print x
  func()

The output result is 200. If the variable name num has not been defined as a global variable before, an error message will appear: The variable is not defined. For example:

  def func():
    x = num + 100
    print x
  func()

The output result is: NameError: global name 'num' is not defined.

3. When a variable is used in a function, if the variable name has both global variables and local variables, the local variable will be used by default. For example:

  num = 100
  def func():
    num = 200
    x = num + 100
    prinx x
  func()

The output result is 300.

4. When defining a variable as a global variable in a function, you need to use the keyword global. For example:

  num = 100
  def func():
    global num
    num = 200
    print num
  func()
  print num

The output results are 200 and 200 respectively. This shows that the variable name num in the function is defined as a global variable and is assigned a value of 200. Another example:

  num = 100
  def func():
    global num
    num = 200
    num += 100
    print num
  func()
  print num

The output results are 300 and 300 respectively.

Combined with the above results of the application scenarios of global variables and local variables, I tried to do some analysis on the first half of the teaching code in the input fields (comments on the Chinese part):

  # calculator with all buttons

  import simplegui

  # intialize globals
  store = 0
  operand = 0

Using the simplegui module, it can be operated without error at http://www.codeskulptor.org/. However, this module cannot be used directly in the python environment, and the SimpleGUICS2Pygame package needs to be installed first.

  # event handlers for calculator with a store and operand

  def output():
  """prints contents of store and operand"""
    print "Store = ", store
    print "Operand = ", operand
    print ""

The global variables store and operand are used directly in the defined function output(). You can refer to point 2.

  def swap():
  """ swap contents of store and operand"""
    global store, operand
    store, operand = operand, store
    output()

In the defined function swap(), the global variables of store and operand are first defined. If you don't do this, an error message will appear saying that it is used without assigning a value. You can refer to point 1. At the same time, can it be understood this way: in the function swap(), when there is no keyword global, store and operand are default local variables, and it is wrong for the part on the right side of = to be used without assignment. You can refer to point 3.

  def add():
  """ add operand to store"""

    global store
    store = store + operand
    output()

Here I encountered the first problem since studying the two-week course: that is why the add() function only defines store as a global variable and does not define operand in the same way. Now combined with point 1, it is because store as a local variable has not been assigned a value in advance and cannot be used directly, while operand can be used by directly calling the previously defined global variable.

Variable scope
Variable scope (scope) is an easy place to fall into a trap in Python.
Python has a total of 4 scopes, which are:

L (Local) local scope
E (Enclosing) in a function outside the closure function
G (Global) global Scope
B (Built-in) Built-in scope
is searched according to the rules of L --> E --> G -->B, that is: if it is not found locally, it will be searched If you look for local parts outside the local area (such as closures), if you can't find them again, you will go to the global search, and then go to the built-in ones.

Except for def/class/lambda in Python, others such as: if/elif/else/ try/except for/while cannot change its scope. Variables defined within them can still be accessed from the outside.

>>> if True:
...   a = 'I am A'
... 
>>> a
'I am A'

Variable a defined in the if language is still accessible from the outside.
But it should be noted that if if is wrapped by def/class/lambda and assigned internally, it becomes the local scope of this function/class/lambda.
Assignment within def/class/lambda becomes its local scope. The local scope will cover the global scope, but will not affect the global scope.

g = 1 #全局的
def fun():
  g = 2 #局部的
  return g

print fun()
# 结果为2
print g
# 结果为1

But be aware that sometimes you want to reference global variables inside a function, and errors will occur if you neglect them. For example:

#file1.py
var = 1
def fun():
  print var
  var = 200
print fun()

#file2.py
var = 1
def fun():
  var = var + 1
  return var
print fun()

Both functions will report the error UnboundLocalError: local variable 'var ' referenced before assignment
Error in referenced before assignment! Why? Because inside the function, the interpreter detects that var has been reassigned, so var becomes a local variable, but if you want to use var before it has been assigned, this error will occur. The solution is to add globals var inside the function, but the global var will also be modified after running the function.

闭包Closure
闭包的定义:如果在一个内部函数里,对在外部函数内(但不是在全局作用域)的变量进行引用,那么内部函数就被认为是闭包(closure)

函数嵌套/闭包中的作用域:

a = 1
def external():
  global a
  a = 200
  print a

  b = 100
  def internal():
    # nonlocal b
    print b
    b = 200
    return b

  internal()
  print b

print external()

一样会报错- 引用在赋值之前,Python3有个关键字nonlocal可以解决这个问题,但在Python2中还是不要尝试修改闭包中的变量。 关于闭包中还有一个坑:

from functools import wraps

def wrapper(log):
  def external(F):
    @wraps(F)
    def internal(**kw):
      if False:
        log = 'modified'
      print log
    return internal
  return external

@wrapper('first')
def abc():
  pass

print abc()

也会出现 引用在赋值之前 的错误,原因是解释器探测到了 if False 中的重新赋值,所以不会去闭包的外部函数(Enclosing)中找变量,但 if Flase 不成立没有执行,所以便会出现此错误。除非你还需要else: log='var' 或者 if True 但这样添加逻辑语句就没了意义,所以尽量不要修改闭包中的变量。

好像用常规的方法无法让闭包实现计数器的功能,因为在内部进行 count +=1 便会出现 引用在赋值之前 的错误,解决办法:(或Py3环境下的 nonlocal 关键字)

def counter(start):
    count =[start]
    def internal():
      count[0] += 1
      return count[0]
    return internal

count = counter(0)
for n in range(10):
  print count()
# 1,2,3,4,5,6,7,8,9,10

count = counter(0)
print count()
# 1

由于 list 具有可变性,而字符串是不可变类型。

locals() 和 globals()
globals()
global 和 globals() 是不同的,global 是关键字用来声明一个局部变量为全局变量。globals() 和 locals() 提供了基于字典的访问全局和局部变量的方式

比如:如果函数1内需要定义一个局部变量,名字另一个函数2相同,但又要在函数1内引用这个函数2。

def var():
  pass

def f2():
  var = 'Just a String'
  f1 = globals()['var']
  print var
  return type(f1)

print f2()
# Just a String
# <type &#39;function&#39;>

locals()
如果你使用过Python的Web框架,那么你一定经历过需要把一个视图函数内很多的局部变量传递给模板引擎,然后作用在HTML上。虽然你可以有一些更聪明的做法,还你是仍想一次传递很多变量。先不用了解这些语法是怎么来的,用做什么,只需要大致了解locals()是什么。
可以看到,locals()把局部变量都给打包一起扔去了。

@app.route(&#39;/&#39;)
def view():
  user = User.query.all()
  article = Article.query.all()
  ip = request.environ.get(&#39;HTTP_X_REAL_IP&#39;,     request.remote_addr)
  s = &#39;Just a String&#39;
  return render_template(&#39;index.html&#39;, user=user,
      article = article, ip=ip, s=s)
  #或者 return render_template(&#39;index.html&#39;, **locals())

The above is the detailed content of Comprehensive analysis of the scope of variables in Python starting from local variables and global variables. For more information, please follow other related articles on the PHP Chinese website!

Statement:
The content of this article is voluntarily contributed by netizens, and the copyright belongs to the original author. This site does not assume corresponding legal responsibility. If you find any content suspected of plagiarism or infringement, please contact admin@php.cn