Python中的作用域==和is的区别及说明
作者:夜阑卧听风吹雨,铁马冰河入梦来
作用域
LEGB规则:
locals -> enclosing function -> globals -> builtins,依次是局部作用域---->嵌套作用域————>全局作用域——>内建作用域
globals()和locals()函数可以获取当前的全局和局部作用域的所有变量
在Python中并不是所有的语句块中都会产生作用域。
只有当变量在Module(模块)、Class(类)、def(函数)中定义的时候,才会有作用域的概念。
需要注意的是:
在if-elif-else、for-else、while、try-except\try-finally等关键字的语句块中并不会产成作用域。
if True: a = 100 print(a) -----100
L(local)局部作用域
局部变量:
包含在def关键字定义的语句块中,即在函数中定义的变量。
每当函数被调用时都会创建一个新的局部作用域。
需要在函数内部定义全局变量,这时可以使用global关键字来声明变量的作用域为全局。
局部变量仅暂时存在,依赖创建该局部作用域的函数是否处于活动的状态。
E(enclosing)嵌套作用域
E也包含在def关键字中,E和L是相对的,E相对于更上层的函数而言也是L。
与L的区别在于,对一个函数而言,L是定义在此函数内部的局部作用域,而E是定义在此函数的上一层父级函数的局部作用域。
主要是为了实现Python的闭包,而增加的实现。
G(global)全局作用域
即在模块层次中定义的变量,每一个模块都是一个全局作用域。
也就是说,在模块文件顶层声明的变量具有全局作用域,从外部开来,模块的全局变量就是一个模块对象的属性。
注意:
全局作用域的作用范围仅限于单个模块文件内
B(built-in)内置作用域
系统内固定模块里定义的变量,如预定义在builtin 模块内的变量。
variable = 300 def test_scopt(): print (variable) #variable是test_scopt()的局部变量,但是在打印时并没有绑定内存对象。 variable = 200 #因为这里,所以variable就变为了局部变量 test_scopt() print (variable)
上述例子会报UnboundLocalError,因为在执行程序时的预编译能够在test_scopt()中找到局部变量variable(对variable进行了赋值)。
在局部作用域找到了变量名,所以不会升级到嵌套作用域去寻找。
但是在使用print语句将变量variable打印时,局部变量variable并有没绑定到一个内存对象(没有定义和初始化,即没有赋值)。
本质上还是Python调用变量时遵循的LEGB法则和Python解析器的编译原理,决定了这个错误的发生。
所以,在调用一个变量之前,需要为该变量赋值(绑定一个内存对象)。
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。