第一步:弄清楚全局变量,局部变量,自由变量
global_var = 100 # 写在模块里的变量称为全局变量
def outer():
external_var = 99 # 写在函数里边的称为局部变量,因为他放在outer函数这一整块内存里边
def inner():
local_var = external_var # 在内部函数里本地变量local_var引用了外部函数的external_var变量
print(local_var)
return inner
inn = outer() # 这里inn接收了内部函数inner,inner函数又引用了external_var变量,这时external_var就成了一个自由变量
inn()
# 显示99
第二步:弄清楚闭包
闭包就是一个把自由变量封闭起来的包,其实就是一个函数把别人的变量给闭起来给自己用。上面代码中,内部函数inner把外部函数的external_var变量给引用了,然后return inner给变量inn。当outer函数执行完毕,external_var变量被回收后,嵌套函数(内部函数)inner仍然能使用external_var,并且打印出来external_var的值99。像这样,本身没有定义一个变量(inner函数并没有定义external_var),但是却使用了它(inner函数引用了external_var),并且将函数自身返回,则称这个返回的函数为闭包。上面代码中inner就是一个闭包,同时inn变量又指向了inner。
第三步:弄清楚函数可以作为参数
在python中,函数可以作为变量,作为另一个函数的参数。并且通过在变量后面加上括号()来执行。比如inn指向的是闭包inner,inn()就是执行了该闭包。
第四部:类比
在上面的代码中,嵌套函数inner把外部变量external_var给闭起来给自己用,很明显external_var是一个整数类型,那么可不可以把一个函数类型给闭起来呢?答案是可以的。看下面的代码。
def test():
print('我将会被嵌套函数给闭起来')
def outer(func):
def inner():
func_copy = func # 在内部函数里引用了外部变量func,而func指向的是test函数,inner把func/test给闭起来了
func_copy() # 执行func_copy,其实就是执行了test函数
return inner
inn = outer(test) # 这里把函数test作为变量传递给了outer函数
inn()
# 我将会被嵌套函数给闭起来
第五步:弄清楚装饰器
理解装饰器的概念,首先要弄清楚装饰器是用来干什么的。装饰器的作用就是在不修改一个函数的前提下,给这个函数增增加新的功能(我们都知道一般一个函数只实现一个功能)。怎么来实现这个目的呢?有一个方法就是使用闭包来实现。
def decoration(func):
def wrapper():
func_copy = func
print('在被修饰函数执行前先执行一些其他功能') # 需要装饰的内容代码写在这里,也可以接受其他函数在这里执行
func_copy()
print('在被修饰函数执行后在执行一些其他功能')
return wrapper
# old_func将要增加新功能,他将要被装饰
def old_func():
print('我是需要增加功能的函数')
old_func() # 被装饰之前先看看自己长什么样
# 打印出:我是需要增加功能的函数
# 我是old_func函数,我用下面的代码来装饰自己,但是我自身功能不会改变,所以还是用我原来的名字来接受被装饰的自己
old_func = decoration(old_func)
old_func() # 我已经被装饰了,运行一下看看
# 打印出下面的内容
# 在被修饰函数执行前先执行一些其他功能
# 我是需要增加功能的函数
# 在被修饰函数执行后在执行一些其他功能
当然也可以采用语法糖的形式来实现函数的装饰。
def decoration(func):
def wrapper():
func_copy = func
print('在被修饰函数执行前先执行一些其他功能') # 需要装饰的内容代码写在这里,也可以接受其他函数在这里执行
func_copy()
print('在被修饰函数执行后再执行一些其他功能')
return wrapper
# old_func将要增加新功能,他将要被装饰,这次使用@decoration来装饰自己
@decoration
def old_func():
print('我是需要增加功能的函数')
# @decoration等价于执行old_func = decoration(old_func)这句代码
old_func() # 我已经被装饰了,运行一下看看
# 打印出下面的内容
# 在被修饰函数执行前先执行一些其他功能
# 我是需要增加功能的函数
# 在被修饰函数执行后在执行一些其他功能
以上就是装饰器基本的使用方法,不足之处请大家指出。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)