Parsing the scope of variables in Python from local and global variables

高洛峰
Release: 2017-03-02 11:10:08
Original
1643 people have browsed it

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()
Copy after login

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()
Copy after login

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()
Copy after login

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()
Copy after login

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()
Copy after login

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
Copy after login

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
Copy after login

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
Copy after login

The simplegui module is called here and can be operated without error at //m.sbmmt.com/. 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 ""
Copy after login

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()
Copy after login

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()
Copy after login

Here I encountered the first problem since the two-week course: that is why only store is defined as a global variable in the add() function , without defining 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'
Copy after login

Variable a defined in the if language can still be accessed 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
Copy after login

But be aware that sometimes you want to reference global variables inside a function, and errors will occur if you are not careful, such as:

#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()
Copy after login

这两个函数都会报错UnboundLocalError: local variable 'var' referenced before assignment
在未被赋值之前引用的错误!为什么?因为在函数的内部,解释器探测到var被重新赋值了,所以var成为了局部变量,但是在没有被赋值之前就想使用var,便会出现这个错误。解决的方法是在函数内部添加 globals var 但运行函数后全局的var也会被修改。

闭包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()
Copy after login

一样会报错- 引用在赋值之前,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()
Copy after login

也会出现 引用在赋值之前 的错误,原因是解释器探测到了 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
Copy after login

由于 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;>
Copy after login

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())
Copy after login

更多从局部变量和全局变量解析Python中变量的作用域相关文章请关注PHP中文网!


Related labels:
source:php.cn
Statement of this Website
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
Popular Tutorials
More>
Latest Downloads
More>
Web Effects
Website Source Code
Website Materials
Front End Template
About us Disclaimer Sitemap
php.cn:Public welfare online PHP training,Help PHP learners grow quickly!