effective-python中,在阐述作用域变量时提到了nonlocal和global,当提到python2没有nonlocal时,实现了其功能,这例子没读懂:
# Python2
def sort_priority(values, group):
found = [False]
def helper(x):
if x in group:
found[0] = True
return (0, x)
return (1, x)
values.sort(key=helper)
return found[0]
重中之重:基础,赶紧查查资料:
1. 全局变量与局部变量
全局变量为定义在函数外部的变量
局部变量为定义在函数内部的变量
2. 定义
golobal 指定全局变量
nonlocal 指定上一级变量
3. 特性
参考链接:https://www.cnblogs.com/echoboy/p/8973266.html
4. 注意点:
global是作用在全局的,并不能修改函数内的变量!
found = 9
def line_conf():
found = "nihao"
def line():
# nonlocal found
global found
found = "hello"
print('found1:', found, id(found))
line()
print('found2:', found, id(found))
print('found0:', found, id(found))
line_conf()
print('found3:', found, id(found))
### 打开global:###
found0: 9 10919680
found1: hello 139819150299184
found2: nihao 139819150391592
found3: hello 139819150299184
### 打开nonlocal:###
found0: 9 10919680
found1: hello 140527291113520
found2: hello 140527291113520
found3: 9 10919680
这个栗子很好的体现了global和nonlocal的作用范围,更体现了一点:当被global和nonlocal定义之后,变量的值是直接修改的。
在闭包中,内嵌函数是可以读上层变量,但是不可写的:
def line_conf():
found = 6
def line():
# found = 8
print('found1:', found, id(found))
line()
print('found2:', found, id(found))
line_conf()
### found = 8 注释了 ###
found1: 6 10919584
found2: 6 10919584
### 打开 found = 8 ###
found1: 8 10919648
found2: 6 10919584
读到这里,之前的疑惑就可以解开了:
为什么可以用list起到nonlocal的作用?
因为found变量在内层函数是不可以写上一层的,但是可以读(因为没修改id),所以我们把found设置成列表,让解释器去上一层读取这个列表(也就是说只要在不改变id的前提下就可以拿到上层的变量),注意!上面的栗子证明,nonlocal和global都是直接修改变量的(也就是id),列表的修改是不改变id的,所以,在这里使用列表也可以达到nonlocal的效果。
Python2
def sort_priority(values, group):
found = [False]
def helper(x):
if x in group:
found[0] = True
return (0, x)
return (1, x)
values.sort(key=helper)
return found[0]
print('Found:', sort_priority(values, group))
print(values)
### ###
Found: True
[7, 9, 1, 2, 3, 4, 5, 6, 8]
网友评论