Python中的闭包与装饰器

关于闭包:使用了外部函数变量的内部函数

使用闭包函数的目的:保存函数内的变量,而不会随着函数调用完而被摧毁

# 用于求和的闭包, 外部函数有参数num1, 内部函数有参数num2, 然后调用, 求两个整数和
# 1. 定义外部函数.
def func_outer(num1):          
    # 2. 定义内部函数
    def func_inner(num2):      
        # 3. 求和.
        sum = num1 + num2      
        print(f'求和结果为: {sum}')
    # 4. 返回内置函数名.
    return func_inner           

# 5. 调用func_outer函数
my_fn = func_outer(3)       # 等价于: my_fn = func_inner
my_fn(5)    
>> 8
my_fn(6)   
>> 9 

有一种调用闭包函数的特殊写法,以上述函数为例:

func_outer(10)(20) 
>> 30

介绍一下与之相关的两个函数global,noolocal:

global :在函数中使用,更改全局变量

# 定义变量
a = 1
# 定义函数
def fun_outer():
    # 更改全局变量
    global a
    a = 100
    print(a)

# 3. 调用函数.
fun_outer()
>> 100

noolocal :在内部函数中使用,更改外部函数的变量

# 1. 定义外部函数
def fun_outer():
    # 定义外部函数的变量
    a = 100
    # 2. 定义内置函数.
    def fun_inner():
        nonlocal a
        print(f'a的值为: {a}')
    return fun_inner            
# 3. 调用函数.
my_fun = fun_outer()
my_fun()

noolocal在闭包函数中可以作为累加器计算:

# 1. 定义外部函数
def fun_outer():               
    # 定义外部函数的变量
    a = 100

    # 2. 定义内置函数.
    def fun_inner():          
        nonlocal a
        a = a + 1              
        print(f'a的值为: {a}')
    return fun_inner          

# 3. 调用函数.
my_fn = fun_outer()
my_fn()  
>> a的值为: 101
my_fn()  
>> a的值为: 102
my_fn()    
>> a的值为: 103

关于装饰器:实际上就是一个闭包函数

装饰器的产生是为了不改变原有的函数,而给这个函数添加新的功能

# 1. 定义装饰器.
def print_info(fn_name):    # fn_name: 表示要被装饰的函数名                   
    def fn_inner():         # 内置函数, 格式要和 原函数(被装饰的函数) 保持一致.  
        print('[友好提示] 正在努力计算中...')                               
        fn_name()                                                      
    return fn_inner                                                    

# 2. 定义原函数(即: 要被装饰的函数)
@print_info         # 这个是语法糖写法, 等价于: get_sum = print_info(get_sum)
def get_sum():
    a = 10
    b = 20
    sum = a + b
    print(f'求和结果为: {sum}')

# 3. 调用原函数.
get_sum()

使用装饰器时要注意:内置函数的格式要与原函数(被调用函数)格式保持一致即参数与返回值保持一致。

同一个函数可以被多个装饰器同时装饰

# 1. 定义装饰器, 实现: 登录用户
def check_user(fn_name):       
    def inner():               
        print('--- 我在登陆账号, 校验登陆 ---')   
        fn_name()              
    return inner               

# 2. 定义装饰器, 实现: 验证码校验
def check_code(fn_name):
    def inner():        
        print('--- 验证码验证! ---') 
        fn_name()      
    return inner       

# 3. 定义函数, 实现: 评论功能.
@check_user
@check_code
def comment():
    print('我来发表评论了...')

# 4. 调用, 语法糖形式.
comment()

总结一下:

闭包函数需满足三个条件:有嵌套,有引用(在内部函数使用了外部函数的变量),有返回(外部函数中返回了内部函数)

装饰器:是一个闭包函数,同时满足要有新加的功能,并且内置函数与原函数格式保持一致。

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值