简介:Python 装饰器可帮助我们抽离出大量函数中与函数功能本身无关的雷同代码,并继续重用。
1、函数的作用域LEGB
首先来介绍一下什么是LEGB:
L:(local)局部作用域。就是函数中定义的变量
E:(enclosing)嵌套的父级函数的局部作用域。即包含此函数的上级函数的局部作用域,但不是全局的
G:(global)全局作用域。就是模块级别定义的变量;
B:(build-in)内置作用域。系统固定模块里面的变量
python解释器查找变量的规则:L>E>G>B
通过如下练习来认识一下LEGB:
场景设置:判断一个学生的成绩是否及格(60分为及格):
# *-*coding:utf-8*-*
passline = 60
def func(val):
if val >= passline:
print 'pass'
else:
print 'failed'
func(89)
运行结果:
解释:当定义一个函数的时候,就会引用一个作用域,这个作用域就是local;当对func进行调用的时候,val就是本地的变量,所以函数执行的过程中python解释器就会从函数参数中找到val。 但是passline并不在函数的内部,这个时候python解释器就会从全局变量中去寻找passline,当全局变量中还没有的话,就继续向上查找。
场景设置二:当分数为150,90分算及格的时候,为了验证local作用域最为优先,在场景一的基础下做修改:
# *-*coding:utf-8*-*
passline = 60
def func(val):
passline = 90
if val >= passline:
print 'pass'
else:
print 'failed'
func(89)
运行结果:
解释:可以看到,在寻找passline的时候,优先选择了函数内部的变量(local作用域),当解释器在loca作用域中找不到passline,才会去函数外部查找。
总结:
首先,是local,先查找函数内部
然后,是enclosing,再查找函数内部与嵌入函数之间(是指在函数内部再次定义一个函数)
其次,是global,查找全局
最后,是build-in,内置作用域
2、python闭包
闭包的概念:内部函数中对enclosing作用域的变量进行引用
理解一下:如果一个函数的内部定义了另一个函数,外部的我们叫它外函数,内部的我们叫它内函数。当内函数内运用了外函数的临时变量,并且外函数的返回值是内函数的引用,这样就构成了一个闭包。
举例1:
# *-*coding:utf-8*-*
def set_passline(passline):
def cmp(val):
if val >= passline:
print 'Pass'
else:
print 'Failed'
return cmp
f_100 = set_passline(60)
f_150 = set_passline(90)
f_100(89)
f_150(89)
运行结果:
举例2:
# *-*coding:utf-8*-*
#闭包函数的实例
#outer是外部函数,a和b都是外函数的临时变量
def outer(a):
b = 10
# inner是内函数
def inner():
# 在内函数中,用到了外函数的临时变量
print a + b
# 外函数的返回值是内函数的引用
return inner
if __name__=='__main__':
# 在这里调用外函数传入参数5
# 此时,外函数的两个临时变量a是5,b是10,并创建了内函数,然后把内函数的引用返回存给了demo
# 外函数结束的时候发现内部函数相会用到自己的临时变量,这两个临时变量就不会被释放,会绑定给这个内部函数
demo = outer(5)
# 我们调用内部函数,看一看内部函数是不是能使用外部函数的临时变量
# demo存了外函数的返回值,也就是inner函数的引用,这里相当于执行inner函数
demo()
demo2 = outer(7)
demo2()
运行结果: