千家信息网

python闭包和装饰器怎么用

发表于:2025-02-01 作者:千家信息网编辑
千家信息网最后更新 2025年02月01日,这篇"python闭包和装饰器怎么用"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"p
千家信息网最后更新 2025年02月01日python闭包和装饰器怎么用

这篇"python闭包和装饰器怎么用"文章的知识点大部分人都不太理解,所以小编给大家总结了以下内容,内容详细,步骤清晰,具有一定的借鉴价值,希望大家阅读完这篇文章能有所收获,下面我们一起来看看这篇"python闭包和装饰器怎么用"文章吧。

一、闭包

闭包的形成条件:

1.函数嵌套。

2.内部函数使用了外部函数的变量或者参数。

3.外部函数返回了使用外 部变量的内部函数。

二、一个简单的例子

def func_out(num1):    def inner(num2):        res = num1 + num2        print(res)    return inner# a = func_out(10)(10)a = func_out(10)a(10)

闭包修改外部函数的变量:

在闭包内修改外部函数的变量需要使用nonlocal关键字

def func_out():    # 外部函数的变量    num1 = 10    def func_inner():        # 在闭包内修改外部函数的变量        nonlocal num1        num1 = 20        res = num1 +20        print(res)    print("修改前的变量", num1)    func_inner()    print("修改后的变量", num1)    return func_innernew_func = func_out()new_func()

三、装饰器

3.1 简单装饰器

装饰器就是给已有函数增加额外功能的函数,它本质上就是一个闭包函数,也就是说也是一个函数嵌套。装饰器的功能特点:

1.不修改已有函数的源代码

2.不修改已有函数的调用方式

3.给已有函数增加额外的功能

用户在发表评论的时候需要验证用户是否登录,我们首先会想到去修改原来的函数,在函数里面添加一些功能,但是在现在这分工合作的时代,这样的修改很容易出现修改了祖传的代码后,函数出现问题,也影响代码的高效复用。为了能够不重新修改原来的评论的代码,实现高水平的代码复用。

原本的函数及其调用:

def comment():    print("执行祖传代码.....")    print("发表评论")# 调用评论功能comment()

自己手写一个实现装饰器功能的函数实现登录验证:

def decorator(func):    def inner():        print('正在验证登录者身份...验证成功')        func()    return innerdef comment():    print("执行祖传代码.....")    print("发表评论")# 调用评论功能comment = decorator(comment)comment()

输入结果:

正在验证登录者身份…
验证成功
执行祖传代码…
发表评论

3.1.1 使用装饰器的语法糖

装饰器的语法糖写法:@装饰器名称

如例子可以改写为:

def decorator(func):    def inner():        print('正在验证登录者身份...验证成功')        func()    return inner@decoratordef comment():    print("执行祖传代码.....")    print("发表评论")# 调用函数comment()

运行结果:

正在验证登录者身份…
验证成功
执行祖传代码…
发表评论

3.1.2 装饰器的执行时机

先说结论:在使用装饰器语法糖时,会先将该装饰器函数执行一遍。

def decorator(func):    # 测试装饰器的执行时机    print('--remark1----')    def inner():        print('正在验证登录者身份...验证成功')        func()    print('----remark2---')    return inner@decoratordef comment():    print("执行祖传代码.....")    print("发表评论")

输出结果:

-remark1----
----remark2-

3.2 通用装饰器

装饰的函数可能有参数传递,或者有返回值,上面写的例子中,如果依然用上面的方法及逆行装饰器的装饰将会出现问题,那是否有一个通用的装饰器能够装饰任意函数呢?

3.2.1 装饰带有参数的函数
def logging(fn):    def inner(num1,num2):        print('执行了一次计算')        fn(num1,num2)    return inner# 使用装饰器装饰函数@loggingdef sum_num(a,b):    result = a + b    print(result)    sum_num(1,2)
3.2.2. 装饰带有返回值的函数:
def logging(fn):    def inner(num1,num2):        print('执行了一次计算')        result = fn(num1,num2)        return result        return inner# 使用装饰器装饰函数@loggingdef sum_num(a,b):    result = a + b    return result    print(sum_num(1,2))
3.2.3 实现通用装饰器

*args: 用于接收元组参数,可传可不传

**kwargs: 用于接收字典类型参数,可传可不传

def logging(fn):    def inner(*args, **kwargs):        result = fn(*args, **kwargs)        return result    return inner@loggingdef sum_num(a,b):    result = a + b    return result

3.3 多个装饰器的使用

多个装饰器的过程:由内到外的装饰过程,先执行内部装饰器,再执行外部装饰器。

原理剖析:content = make_div(make_p(content))

分步拆解:content = make_p(content), 内部装饰器完成content=make_p.inner, content = make_div(make_p.inner)

def make_div(func):    print("make_div装饰器执行了")    def inner():        # 在内部函数对已有函数进行装饰        result = "
" + func() +"
" return result return innerdef make_p(func): print("make_p装饰器执行了") def inner(): # 在内部函数对已有函数进行装饰 result = "

" + func() +"

" return result return inner@make_div@make_pdef content(): return "人生苦短,我用Python"

输出:

make_p装饰器执行了
make_div装饰器执行了

人生苦短,我用Python

3.4 带有参数的装饰器

带有参数的装饰器时机上就是定义了一个函数,让函数接收参数,再函数内部返回该装饰器。

如定义一个能够判断加减的装饰器:

def return_decorator(flag):    def decorator(func):        def inner(a,b):            if flag == '+':                print("正在进行加法运算")            elif flag == '-':                print("正在进行减法运算")            func(a,b)        return inner    return decorator@return_decorator('+')def add_num(a,b):    print(a+b)add_num(1,5)

3.5 类装饰器

使用类装饰已有函数。

class MyDecorator(object):    def __init__(self,func):        self.__func = func    # 实现__call__方法,让对象变成可调用的对象,    # 可调用的对象能够像函数一样被使用。    def __call__(self,*args,**kwargs):        # 对已有参数进行封装        print('--正在进行装饰-----')        self.__func()        @MyDecoratordef show():    print("hello")# 指向MyDecorator类创建实例对象--> show()==> 对象()show()

输出:

-正在进行装饰-----
hello

以上就是关于"python闭包和装饰器怎么用"这篇文章的内容,相信大家都有了一定的了解,希望小编分享的内容对大家有帮助,若想了解更多相关的知识内容,请关注行业资讯频道。

0