python的作用域分别有几种_Python的作用域

如果习惯了C/C++,Java这类静态语言的作用域规则,那么在Python中就要格外注意。在代码中,我们经常会碰到同一个变量名出现在多个地方,它的作用域可能是不一样的。Python中有四种作用域:局部作用域,嵌套作用域(也就是闭包),全局作用域和内建作用域。在Python代码的任意位置,都应遵循这样的搜索规则:局部 > 嵌套 > 全局 > 内建,这种搜索顺序也被称为: LEGB(4个单词首字母缩写)。Python中作用域由def, class, lambda 等语句产生,而 if, try, for等语句并不会产生新的作用域。下面以代码说明下这种名字搜索域规则:

>>> x = 9 #x是全局变量

>>> deffunc():print x #x是局部变量

x += 1

>>>func()

Traceback (most recent call last):

File"", line 1, in func()

File"", line 2, infuncprintx

UnboundLocalError: local variable'x' referenced before assignment

解释器报错,告诉我们print x 这句出错,原因是局部变量x 引用时未被赋值。我们用上面的作用域规则来分析:

1. print x 所在的代码位置是函数内,解释器从当前位置按LEGB的顺序去找x这个变量,发现在当前函数内有一个局部变量x。那么,此时就停止名字搜索;

2. print x 所处函数的第一行,尽管x是在本函数内找到了,但是在执行 print x 这条语句时,x 是未被赋值的。所以引发一个异常。这也是上面报错原因。

如果像上面的函数内有个局部变量和函数外的全局变量同名,此时想引用全局变量,则要使用global关键字,来申明你在函数中使用全局变量:

>>> x = 9 #x是全局变量

>>> deffunc():globalxprint x #x是全局变量

x += 1

returnx>>>func()10

11

但是上面的这种写法不太好,更好的写法是用类封装起来,如:

>>> classvar_x(object):

x= 9

>>> deffunc():print var_x.x #类的全局变量

x =0

var_x.x= 8 #局部变量

printx>>>func()90

我们再来看下嵌套作用域下变量是如何被执行的。这里所说的嵌套,是指函数的嵌套,也就是所谓的闭包。如:

>>> deffoo():

func= lambda: 'value of x: %s' % x #嵌套函数

try:printfunc()exceptException, e:print 'ERROR:', e

x= 10

printfunc()

x= 'spam'

printfunc()>>>foo()

ERROR: free variable'x' referenced before assignment inenclosing scope

value of x:10value of x: spam

上面函数中的嵌套函数是lambda,不要忘了lambda是匿名函数。当第一次打印 func()时,父作用域中的x还未赋值,所以报错。而后面两次的调用,x已经有值,所以正常打印出结果。可以看出嵌套函数可以访问上级函数父作用域中的变量。

如果你非要看有def定义的函数嵌套觉得会更清楚,那么:

>>> defouter_func():

x= 3

definner_func1():print 'inner func 1:', xdefinner_func2():

x= 'hello'

print 'inner func 2:', x

inner_func1()

inner_func2()print 'outer func:', x>>>outer_func()

inner func1: 3inner func2: hello

outer func:3

总结:

1. Python 对名字的搜索顺序是:Local > Enclosing > Global > Built-in;

2. 在函数内引用全局变量时,要使用global关键字先声明。或者通过类对变量进行封装;

3. 嵌套作用域中的嵌套函数,可以访问父级作用域中的变量;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值