# -*- encoding: utf-8 -*-
import copy
'''
第15条: 了解如何在闭包里使用外围作用域中的变量
关键:
1 闭包
含义:定义在某个作用域中的函数,这种函数引用了该作用域的变量。
特点: 函数是可以作为参数传递给其他函数
元组比较规则: 先比较元组中下标为0的元素,然后比较下标为1的元素
2 解析引用的顺序
1) 当前函数的作用域
2) 任何外围作用域(当前函数的其他函数)
3) 包含当前代码的那个模块的作用域(全局作用域)
4) 内置作用域(也就是包含len或str等函数的作用域)
解释:
易错: 在闭包里面的赋值相当于重新定义了一个新的变量,而不是用闭包外面定义的同名变量
原因: 防止函数中的局部变量影响函数外面的变量,如果不这样做,
函数内的局部变量复制都会影响外围模块的全局作用域
示例代码:
def sortPriorityNotInfluenceExternalScope(values, group):
found = False
def helper(value):
if value in group:
found = True
return (0, value)
return (1, value)
values.sort(key=helper)
print found
return values
解决办法: 利用列表是可修改的,能从闭包内影响闭包外的变量
代码示例如下:
def sortPriorityInfluenceExternalScope(values, group):
found = [False]
def helper(value):
if value in group:
# 充分利用列表可修改的特点来实现闭包内影响闭包外变量
found[0] = True
return (0, value)
return (1, value)
values.sort(key=helper)
print found[0]
return values
3 总结
1) 作用域中的闭包可以引用作用域中的变量
2) 默认方式对闭包内变量赋值,不影响外围作用域
3) python3用 nonlocal影响外围作用域中的变量
参考:
Effectiv Python 编写高质量Python代码的59个有效方法
'''
def sortPriority(values, group):
def helper(x):
if x in group:
return (0, x)
return (1, x)
values.sort(key=helper)
return values
def sortPriorityNotInfluenceExternalScope(values, group):
found = False
def helper(value):
if value in group:
found = True
return (0, value)
return (1, value)
values.sort(key=helper)
print found
return values
def sortPriorityInfluenceExternalScope(values, group):
found = [False]
def helper(value):
if value in group:
# 充分利用列表可修改的特点来实现闭包内影响闭包外变量
found[0] = True
return (0, value)
return (1, value)
values.sort(key=helper)
print found[0]
return values
# def sortPriorityInfluenceExternalScope(values, group):
# found = False
# def helper(value):
# nonlocal found
# if value in group:
# return (0, value)
# return (1, value)
# values.sort(key=helper)
# return values
def process():
values = [8, 3, 1, 2, 5, 4, 7, 6]
valuesCopy = copy.deepcopy(values)
valuesCopy2 = copy.deepcopy(values)
group = {2, 3, 5, 7}
result = sortPriority(values, group)
print result
print valuesCopy
print valuesCopy2
# sortPriorityNotInfluenceExternalScope(valuesCopy, group)
result = sortPriorityInfluenceExternalScope(valuesCopy2, group)
print result
if __name__ == "__main__":
process()