python闭包

目录

一,全局变量,局部变量,自由变量的区别

二,闭包的概念

三,函数是一等公民,函数名可以作为参数

四,将一个函数对象闭起来

五,详解装饰器


一,全局变量,局部变量,自由变量的区别

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变量给引用了。然后把内部函数inner以及自由变量external_var打包返回给变量inn。当outer函数执行完毕,external_var变量本应该被回收,但是嵌套函数(内部函数)inner仍然能使用external_var,并且打印出来external_var的值99。

        像这样,本身没有定义一个变量(inner内部函数并没有定义external_var),但是却使用了它(inner函数引用了external_var),并且将函数自身与自由变量打包返回,则称这个返回的函数为闭包。上面代码中inner就是一个闭包,同时inn变量又指向了内部函数inner,实现了变量inn与内部函数innner的绑定。

三,函数是一等公民,函数名可以作为参数

        在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
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值