美文网首页Python基础系列
Python基础教程:变量的作用域

Python基础教程:变量的作用域

作者: 我爱学python | 来源:发表于2019-08-10 15:37 被阅读12次

1、变量作用域LEGB

1.1变量的作用域

在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空间中进行,我们称之为命名空间,也被称之为作用域。python的作用域是静态的,在源代码中变量名被赋值的位置决定了该变量能被访问的范围。即Python变量的作用域由变量所在源代码中的位置决定。

1.2高级语言对数据类型的使用过程

一般的高级语言在使用变量时,都会有下面4个过程。当然在不同的语言中也会有着区别。

  1. 声明变量:让编辑器知道有这一个变量的存在
  2. 定义变量:为不同数据类型的变量分配内存空间
  3. 初始化:赋值,填充分配好的内存空间
  4. 引用:通过引用对象(变量名)来调用内存对象(内存数据)

1.3作用域的产生

就作用域而言,Python与C有着很大的区别,在Python中并不是所有的语句块中都会产生作用域。只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。看下面的代码:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
#!/usr/bin/env python
def func():
    variable = 100
    print variable
print variable

代码的输出为:

NameError: name 'variable' is not defined

在作用域中定义的变量,一般只在作用域中有效。 需要注意的是:在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。看下面的代码:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
if True:
    variable = 100
    print (variable)
print ("******")
print (variable)

代码的输出为:

100
******
100

所以,可以看到,虽然是在if语句中定义的variable变量,但是在if语句外部仍然能够使用。

1.4作用域的类型:

在Python中,使用一个变量时并不严格要求需要预先声明它,但是在真正使用它之前,它必须被绑定到某个内存对象(被定义、赋值);这种变量名的绑定将在当前作用域中引入新的变量,同时屏蔽外层作用域中的同名变量。

L(local)局部作用域

局部变量:包含在def关键字定义的语句块中,即在函数中定义的变量。每当函数被调用时都会创建一个新的局部作用域。Python中也有递归,即自己调用自己,每次调用都会创建一个新的局部命名空间。在函数内部的变量声明,除非特别的声明为全局变量,否则均默认为局部变量。有些情况需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。局部变量域就像一个 栈,仅仅是暂时的存在,依赖创建该局部作用域的函数是否处于活动的状态。所以,一般建议尽量少定义全局变量,因为全局变量在模块文件运行的过程中会一直存在,占用内存空间。
注意:如果需要在函数内部对全局变量赋值,需要在函数内部通过global语句声明该变量为全局变量。

E(enclosing)嵌套作用域

E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。主要是为了实现Python的闭包,而增加的实现。

G(global)全局作用域

即在模块层次中定义的变量,每一个模块都是一个全局作用域。也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。
注意:全局作用域的作用范围仅限于单个模块文件内

B(built-in)内置作用域

系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。

1.5变量名解析LEGB法则

搜索变量名的优先级:局部作用域 > 嵌套作用域 > 全局作用域 > 内置作用域

LEGB法则: 当在函数中使用未确定的变量名时,Python会按照优先级依次搜索4个作用域,以此来确定该变量名的意义。

首先搜索局部作用域(L),之后是上一层嵌套结构中def或lambda函数的嵌套作用域(E),之后是全局作用域(G),最后是内置作用域(B)。按这个查找原则,在第一处找到的地方停止。如果没有找到,则会出发NameError错误。

几个实例:

'''
遇到问题没人解答?小编创建了一个Python学习交流QQ群:857662006 
寻找有志同道合的小伙伴,互帮互助,群里还有不错的视频学习教程和PDF电子书!
'''
def func():
    variable = 300
    print variable

variable = 100
func() #300
print variable  #100
variable = 300

def test_scopt():

  print variable #variable是test_scopt()的局部变量,但是在打印时并没有绑定内存对象。

  variable = 200 #因为这里,所以variable就变为了局部变量

test_scopt()

print variable

上面的例子会报出错误,因为在执行程序时的预编译能够在test_scopt()中找到局部变量variable(对variable进行了赋值)。

在局部作用域找到了变量名,所以不会升级到嵌套作用域去寻找。但是在使用print语句将变量variable打印时,局部变量variable并有没绑定到一个内存对象(没有定义和初始化,即没有赋值)。

本质上还是Python调用变量时遵循的LEGB法则和Python解析器的编译原理,决定了这个错误的发生。所以,在调用一个变量之前,需要为该变量赋值(绑定一个内存对象)。

注意:为什么在这个例子中触发的错误是UnboundLocalError而不是NameError:name ‘variable’ is not defined。因为变量variable不在全局作用域。

Python中的模块代码在执行之前,并不会经过预编译,但是模块内的函数体代码在运行前会经过预编译,因此不管变量名的绑定发生在作用域的那个位置,都能被编译器知道。Python虽然是一个静态作用域语言,但变量名查找是动态发生的,直到在程序运行时,才会发现作用域方面的问题

相关文章

  • #抬抬小手学Python# Python 之作用域下的 glob

    global 和 nonlocal 作用域 该部分内容涉及 Python 变量作用域相关知识,变量作用域指的是变量...

  • python学习笔记|nonlocal/global

    python中引用变量的顺序为:当前作用域局部变量->外层作用域变量->当前模块中的全局变量->python内置变...

  • 变量作用域

    0. 命名空间 变量作用域1. 变量作用范围:可操作范围2. Python 是静态作用域,变量的作用域源于它在代码...

  • python的作用域

    前言  作用域是程序运行时变量可被访问的范围。 作用域  python变量的作用域很简单,就是LEGB:变量名引用...

  • Python基础重构-1.2数据类型

    1、变量和常量 变量作用域 Python的作用域一共有4种,分别是:L (Local) 局部作用域E (Enclo...

  • Python基础(十四): 函数作用域

    一、基本概念 1、变量的作用域 变量的作用范围: 可操作范围 Python是静态作用域, 也就是说在Python中...

  • Python的闭包与装饰器

    一、python的函数作用域 python的函数作用域的含义,简而言之,即函数执行时变量所在的作用域。在pytho...

  • Python基础教程:变量的作用域

    1、变量作用域LEGB 1.1变量的作用域 在Python程序中创建、改变、查找变量名时,都是在一个保存变量名的空...

  • Python装饰器与闭包!

    闭包是Python装饰器的基础。要理解闭包,先要了解Python中的变量作用域规则。 变量作用域规则 首先,在函数...

  • Python变量作用域范围

    关键词: python;作用域; Variable Scope; 1、Python中能够改变变量作用域的代码段是d...

网友评论

    本文标题:Python基础教程:变量的作用域

    本文链接:https://www.haomeiwen.com/subject/epyrjctx.html