iis服务器助手广告广告
返回顶部
首页 > 资讯 > 后端开发 > Python >详解Python函数式编程之装饰器
  • 795
分享到

详解Python函数式编程之装饰器

2024-04-02 19:04:59 795人浏览 独家记忆

Python 官方文档:入门教程 => 点击学习

摘要

目录一、装饰器的本质:函数闭包(functionclosure):二、装饰器使用方法:保留函数参数和返回值的函数闭包:三、多个装饰器的执行顺序:四、创建带参数的装饰器:总结一、装饰器

一、装饰器的本质:

装饰器(decorator)本质是函数闭包(function closure)的语法糖(Syntactic sugar)

函数闭包(function closure):

函数闭包是函数式语言(函数是一等公民,可作为变量使用)中的术语。函数闭包:一个函数,其参数和返回值都是函数,用于增强函数功能面向切面编程(AOP)

import time
# 控制台打印100以内的奇数:
def print_odd():
    for i in range(100):
        if i % 2 == 1:
            print(i)
# 函数闭包:用于增强函数func:给函数func增加统计时间的功能:
def count_time_wrapper(func):
    def improved_func():
        start_time = time.time()
        func()
        end_time = time.time()
        print(f"It takes {end_time - start_time} S to find all the odds in range !!!")
    return improved_func
if __name__ == '__main__':
    # 调用count_time_wrapper增强函数
    print_odd = count_time_wrapper(print_odd)
    print_odd()

闭包本质上是一个函数,闭包函数的传入参数和返回值都是函数,闭包函数得到返回值函数是对传入函数增强后的结果。

日志装饰器:

def log_wrapper(func):
    """
    闭包,用于增强函数func: 给func增加日志功能
    """
    def improved_func():
        start_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))  # 起始时间
        func()  # 执行函数
        end_time = time.strftime('%Y-%m-%d %H:%M:%S', time.localtime(time.time()))  # 结束时间
        print("Logging: func:{} runs from {} to {}".fORMat(func.__name__, start_time, end_time))
    return improved_func

二、装饰器使用方法:

通过装饰器进行函数增强,只是一种语法糖,本质上跟上个程序(使用函数闭包)完全一致。

import time
# 函数闭包:用于增强函数func:给函数func增加统计时间的功能:
def count_time_wrapper(func):
    def improved_func():
        start_time = time.time()
        func()
        end_time = time.time()
        print(f"It takes {end_time - start_time} S to find all the odds in range !!!")
    return improved_func
# 控制台打印100以内的奇数:
@count_time_wrapper  # 添加装饰器
def print_odd():
    for i in range(100):
        if i % 2 == 1:
            print(i)
if __name__ == '__main__':
    # 使用  @装饰器(增强函数名) 给当前函数添加装饰器,等价于执行了下面这条语句:
    # print_odd = count_time_wrapper(print_odd)
    print_odd()

装饰器在第一次调用被装饰函数时进行增强,只增强一次,下次调用仍然是调用增强后的函数,不会重复执行增强!

保留函数参数和返回值的函数闭包:

  • 之前所写的函数闭包,在增强主要功能函数时,没有保留原主要功能函数的参数列表和返回值。
  • 一个保留参数列表和返回值的函数闭包写法:
def general_wrapper(func):
    def improved_func(*args, **kwargs):
        # 增强函数功能:
        ret = func(*args, **kwargs)
        # 增强函数功能:
        return ret
    return improved_func

优化装饰器(参数传递、设置返回值): 

import time
# 函数闭包:用于增强函数func:给函数func增加统计时间的功能:
def count_time_wrapper(func):
    # 增强函数:
    def improved_func(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"It takes {end_time - start_time} S to find all the odds in range !!!")
        # 原函数返回值
        return result
    return improved_func
# 计算0-lim奇数之和:
@count_time_wrapper
def count_odds(lim):
    cnt = 0
    for i in range(lim):
        if i % 2 == 1:
            cnt = cnt + i
    return cnt
if __name__ == '__main__':
    result = count_odds(10000000)
    print(f"计算结果为{result}!")

三、多个装饰器的执行顺序:

# 装饰器1:
def wrapper1(func1):
    print("set func1")  # 在wrapper1装饰函数时输出
    def improved_func1(*args, **kwargs):
        print("call func1")  # 在wrapper1装饰过的函数被调用时输出
        func1(*args, **kwargs)
        return None
    return improved_func1
# 装饰器2:
def wrapper2(func2):
    print("set func2")  # 在wrapper2装饰函数时输出
    def improved_func2(*args, **kwargs):
        print("call func1")  # 在wrapper2装饰过的函数被调用时输出
        func2(*args, **kwargs)
        return None
    return improved_func2
@wrapper1
@wrapper2
def original_func():
    pass
if __name__ == '__main__':
    original_func()
    print("------------")
    original_func()

这里得到的执行结果是,wrapper2装饰器先执行,原因是因为:程序从上往下执行,当运行到:

@wrapper1
@wrapper2
def original_func():
    pass

这段代码时,使用函数闭包的方式解析为:

original_func = wrapper1(wrapper2(original_func))

所以先进行wrapper2装饰,然后再对被wrapper2装饰完成的增强函数再由wrapper1进行装饰,返回最终的增强函数。

四、创建带参数的装饰器:

装饰器允许传入参数,一个携带了参数的装饰器将有三层函数,如下所示:

import functools
def log_with_param(text):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print('call %s():' % func.__name__)
            print('args = {}'.format(*args))
            print('log_param = {}'.format(text))
            return func(*args, **kwargs)
        return wrapper
    return decorator
@log_with_param("param!!!")
def test_with_param(p):
    print(test_with_param.__name__)
if __name__ == '__main__':
    test_with_param("test")

将其 @语法 去除,恢复函数调用的形式:

# 传入装饰器的参数,并接收返回的decorator函数
decorator = log_with_param("param!!!")
# 传入test_with_param函数
wrapper = decorator(test_with_param)
# 调用装饰器函数
wrapper("I'm a param")

总结

本篇文章就到这里了,希望能够给你带来帮助,也希望您能够多多关注编程网的更多内容! 

--结束END--

本文标题: 详解Python函数式编程之装饰器

本文链接: https://www.lsjlt.com/news/141135.html(转载时请注明来源链接)

有问题或投稿请发送至: 邮箱/279061341@qq.com    QQ/279061341

本篇文章演示代码以及资料文档资料下载

下载Word文档到电脑,方便收藏和打印~

下载Word文档
猜你喜欢
  • 详解Python函数式编程之装饰器
    目录一、装饰器的本质:函数闭包(functionclosure):二、装饰器使用方法:保留函数参数和返回值的函数闭包:三、多个装饰器的执行顺序:四、创建带参数的装饰器:总结一、装饰器...
    99+
    2024-04-02
  • Python函数式编程之装饰器
    原则:对修改是封闭的,对扩展是开放的,方法:一般不修改函数或者类,而是扩展函数或者类一:装饰器 允许我们将一个提供核心功能的对象和其他可以改变这个功能的对象’包裹‘在一起, 使用装饰对象的任何对象与装饰前后该对象的交互遵循完全...
    99+
    2023-01-30
    函数 Python
  • python装饰器1:函数装饰器详解
    装饰器1:函数装饰器 装饰器2:类装饰器 装饰器3:进阶 先混个眼熟 谁可以作为装饰器(可以将谁编写成装饰器): 函数 方法 实现了__call__的可调用类 装饰器可以去装饰谁(谁可以被装饰): 函数 方法 类 基础...
    99+
    2023-01-30
    详解 函数 python
  • Python 函数装饰器详解
    目录使用场景授权(Authorization)日志(Logging)带参数的装饰器在函数中嵌入装饰器装饰器类总结装饰器(Decorators)是 Python 的一个重要部分。简单地...
    99+
    2024-04-02
  • python之装饰器(函数)
    1. 装饰器   遵循的原则:     开闭原则:   对功能的扩展开放  对代码的修改是封闭 # 通用装饰器写法 # 存在的意义: 在不破坏原有函数和原有函数调用的基础上,给函数添加新的功能. def wrapper...
    99+
    2023-01-30
    函数 python
  • Python函数式编程装饰器的示例分析
    这篇文章给大家分享的是有关Python函数式编程装饰器的示例分析的内容。小编觉得挺实用的,因此分享给大家做个参考,一起跟随小编过来看看吧。一、装饰器的本质:装饰器(decorator)本质是函数闭包(function closure)的语法...
    99+
    2023-06-29
  • Python 3 之 装饰器详解
    ------------ 装饰器 -----------------------------------------------------什么是装饰器装饰器是为函数和类指定管理代码的一种方式。装饰器本身的形式是处理其他的可调用对象的可调用...
    99+
    2023-01-31
    详解 Python
  • Python函数式编程之返回函数实例详解
    目录看代码:用filter函数来计算素数用Python高阶函数来实现这个算法:高阶函数实现打印小于100的素数:总结 高阶函数除了可以接受函数作为参数外,还可以把函数作为结...
    99+
    2024-04-02
  • Python函数装饰器的使用详解
    目录装饰器装饰器的定义装饰器的意义装饰器的使用无参装饰器有参装饰器实例练习总结装饰器 装饰器的定义 关于装饰器的定义,我们先来看一段github上大佬的定义: Function de...
    99+
    2024-04-02
  • python基础之装饰器详解
    目录一、前言二、高阶函数三、函数嵌套四、装饰器4.1 被装饰方法带返回值4.2 被装饰方法带参数4.3 验证功能装饰器4.4 验证功能装饰器——带参数一、前言 装...
    99+
    2024-04-02
  • Python学习之装饰器与类的装饰器详解
    目录装饰器装饰器的定义装饰器的用法类中的装饰器类的装饰器 - classmethod类的装饰器 - staticmethod类的装饰器 - property通过学习装饰器可以让我们更...
    99+
    2024-04-02
  • python三大器之装饰器详解
    目录装饰器总结装饰器 讲装饰器之前要先了解两个概念: 对象引用 :对象名仅仅只是个绑定内存地址的变量 def func(): # 函数名仅仅只是个绑定内存地址的...
    99+
    2024-04-02
  • Python语法详解之decorator装饰器
    python 是一门优雅的语言,有些使用方法就像魔法一样。装饰器(decorator)就是一种化腐朽性为神奇的技巧。最近一直都在使用 Tornado 框架,一直还是念念不忘 Flas...
    99+
    2024-04-02
  • python装饰器详解
            python中的装饰器(decorator)一般采用语法糖的形式,是一种语法格式。比如:@classmethod,@staticmethod,@property,@xxx.setter,@wraps(),@func_na...
    99+
    2023-09-01
    python
  • Python装饰器-闭包与函数装饰器
    一、闭包在学习装饰器前,需要先了解闭包的概念。形成闭包的要点:函数嵌套将内部函数作为外部函数的返回值内部函数必须要使用到外部函数的变量下面以一个计算列表平均值的案例来讲解闭包:def make_average(): # 创建一个列表,用来保...
    99+
    2023-05-14
    Python 函数 装饰器
  • Python函数装饰器应用教程
    目录一、什么是函数装饰器二、函数装饰器的执行时机三、变量作用域四、闭包五、保留函数的元数据七、使用lru_cache缓存函数执行结果八、使用singledispatch实现泛型函数九...
    99+
    2024-04-02
  • Python函数的装饰器
    函数的装饰器. 1. 装饰器   开闭原则:         对功能的扩展开放         对代码的修改是封闭     通用装饰器语法: def wrapper(fn): def inner(*args, **kw...
    99+
    2023-01-30
    函数 Python
  • Python函数装饰器--实例讲解
    一、装饰器定义:1.装饰器的本质为函数;2.装饰器是用来完成被修饰函数的附加功能的所以:装饰器是用来完成被修饰函数附属功能的函数 装饰器的要求:1.不能修改被修饰函数的源代码;2.不能更改被修饰函数的运行方式;3.上述两者缺一不可。 二、装...
    99+
    2023-01-31
    函数 实例 Python
  • Python函数式编程之闭包
    -------------------------函数式编程之*******闭包------------------------ Note: 一:简介 函数式编程不是程序必须要的,但是对于简化程序有很重要的作用。 Python...
    99+
    2023-01-30
    函数 Python
  • Java设计模式之装饰模式详解
    目录一、装饰模式引入例子1.1 一般设计1.2 使用继承方式的一般设计存在的问题二、装饰模式2.1 装饰(Decorator)模式中的角色2.2 装饰模式改进设计UML2.3 装饰模...
    99+
    2024-04-02
软考高级职称资格查询
编程网,编程工程师的家园,是目前国内优秀的开源技术社区之一,形成了由开源软件库、代码分享、资讯、协作翻译、讨论区和博客等几大频道内容,为IT开发者提供了一个发现、使用、并交流开源技术的平台。
  • 官方手机版

  • 微信公众号

  • 商务合作