python闭包,装饰器,初学必看

python闭包,装饰器,初学必看,第1张

第一步:弄清楚全局变量,局部变量,自由变量

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()  # 我已经被装饰了,运行一下看看
# 打印出下面的内容
# 在被修饰函数执行前先执行一些其他功能
# 我是需要增加功能的函数
# 在被修饰函数执行后在执行一些其他功能

以上就是装饰器基本的使用方法,不足之处请大家指出。

 

欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/langs/905327.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-05-15
下一篇 2022-05-15

发表评论

登录后才能评论

评论列表(0条)

保存