【Python函数式编程】——装饰器

本文涉及的产品
日志服务 SLS,月写入数据量 50GB 1个月
简介: 装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值 也是一个函数对象。它经常用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。

Python函数式编程——装饰器

在这里插入图片描述

1.什么是装饰器

先看一段代码:

# -*- coding: utf-8 -*-
# @File  : 什么是装饰器.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 19:38


def fun():
    print('洗脸')


fun()  # 调用fun函数
# 洗脸


# 想给fun函数增加 起床 和 吃早点 这两个功能
def test1(func):
    def test2():
        print('起床')
        func()
        print('吃早点')
    return test2


test1(fun)()
# 起床
# 洗脸
# 吃早点
  由于函数也是一个对象,而且函数对象可以被赋值给变量,所以,通过变量也能调用该函数。也可以将函数赋值变量,做参传入另一个函数。
  装饰器本质上是一个Python函数,它可以让其他函数在不需要做任何代码变动的前提下增加额外功能,装饰器的返回值 也是一个函数对象。

  它经常用于有以下场景,比如:插入日志、性能测试、事务处理、缓存、权限校验等场景,装饰器是解决这类问题的绝佳设计。

2.装饰器的作用

装饰器的作用:为已经存在的对象添加额外的功能

看代码代码:

# -*- coding: utf-8 -*-
# @File  : 装饰器.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 19:46


def test1(func):
    def test2():
        print('起床')
        func()
        print('吃早点')
    return test2


@test1  # 装饰器
def fun():
    print('洗脸')


fun()
# 起床
# 洗脸
# 吃早点
  我们没有直接将 fun函数作为参数传入 test1中,只是将 test1函数以@方式装饰在 fun函数上。

  也就是说,被装饰的函数,函数名作为参数,传入到装饰器函数上,不影响fun函数的功能,再此基础上可以根据业务或者功能增加条件或者信息。

(注意:@在装饰器这里是作为Python语法里面的语法糖写法,用来做修饰。)

  但是我们这里就存在一个问题,这里引入魔术方法 __name__ ,这是属于 python 中的内置类属性,它天生就存在于一个 python 程序中,代表对应程序名称,一般一段程序作为主线运行程序时其内置名称就是 __main__ ,当自己作为模块被调用时就是自己的名字。
print(fun.__name__)
# test2
  这并不是我们想要的!输出应该是 fun,这里的函数被 test2替代了。它重写了我们函数的名字和注释文档,那怎么阻止变化呢,Python提供 functools模块里面的 wraps函数解决了问题。

代码实现:

# @Time  : 2022/8/21 20:04

from functools import wraps


def test1(func):
    @wraps(func)  # 使用fun来包装test2
    def test2():
        print('起床')
        func()
        print('吃早点')
    return test2


@test1  # 装饰器
def fun():
    print('洗脸')


fun()
print(fun.__name__)  # fun

在这里插入图片描述

我们在装饰器函数内,作用 funtest2函数上也增加了一个装饰器 wraps还是带参数的,这个装饰器的功能就是不改变使用装饰器原有函数的结构。

3.装饰器记录日志功能

work()函数增加记录日志功能

# -*- coding: utf-8 -*-
# @File  : 装饰器实现记录日志功能.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 20:09

import time
from functools import wraps


def log(fun):
    @wraps(fun)
    def write_log():
        print("[info]--时间是:%s" % time.strftime("%Y-%m-%d %H:%M:%S"))
        fun()
    return write_log


@log
def work():
    print("我在学习Python")


work()

在这里插入图片描述

4.带参装饰器

  我们也看到装饰器 wraps也是带参数的,那我们是不是也可以定义带参数的装饰器呢,我们可以使用一个函数来包裹装饰器,调入这个参数。
# -*- coding: utf-8 -*-
# @File  : 带参数的装饰器.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 21:01

import time
from functools import wraps


def logs(func):
    @wraps(func)
    def write_log(*args, **kwargs):
        print('[info]--时间:%s' % time.strftime('%Y-%m-%d %H:%M:%S'))
        func(*args, **kwargs)
    return write_log


@logs
def work():
    print('我在工作')


@logs
def work2(name1, name2):
    print('%s和%s在工作' % (name1, name2))


work2('张三', '李四')
# [info]--时间:2022-06-24 18:04:04
# 张三和李四在工作

在这里插入图片描述


5.函数做装饰器

把日志写入文件

# -*- coding: utf-8 -*-
# @File  : 把日志写入文件.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 21:14

import time
from functools import wraps


def logger(log_file):
    def logs(fun):
        @wraps(fun)
        def write_log(*args, **kwargs):
            log = "[info]--时间是:%s" % time.strftime('%Y-%m-%d %H:%M:%S')
            print(log)
            with open(log_file, 'a+') as f:
                f.write(log+'\n')
            fun(*args, **kwargs)
        return write_log
    return logs


@logger('work.log')  # 使用装饰器来给 work函数增加记录日志的功能
def work(name1, name2):  # 1.当前 work可能有多个参数 2.自定义日志文件的名字和位置,记录日志级别
    print(f"{name1}和{name2}正在工作")


work('张三', '李四')

终端输出:
在这里插入图片描述
work.log文件记录日志
在这里插入图片描述

  这里我们将带参数的带入进去根据代码流程执行生成了文件并将日志信息打印进去现在我们有了能用于正式环境的 logger装饰器,但当我们的应用的某些部分还比较脆弱时,异常也许是需要更紧急关注的事情。

6.类做装饰器

# -*- coding: utf-8 -*-
# @File  : 把日志写入文件.py
# @author: Flyme awei 
# @email : Flymeawei@163.com
# @Time  : 2022/8/21 21:14

import time
from functools import wraps


class Log(object):
    def __init__(self, log_file, level="INFO"):
        self.log_file = log_file
        self.level = level

    def __call__(self, fun):  # 定义装饰器,需要有一个接受函数
        @wraps(fun)
        def write_log(*args, **kwargs):
            log = "[%s]--时间是:%s" % (self.level, time.strftime('%Y-%m-%d %H:%M:%S'))
            print(log)
            with open(self.log_file, 'a+') as f:
                f.write(log+'\n')
            fun(*args, **kwargs)
        return write_log


@Log('work3.png')
def learn(name):
    print(f"{name}在学习Python")


@Log('work2.log')  # 使用装饰器来给 work函数增加记录日志的功能
def work(name1, name2):  # 1.当前 work可能有多个参数 2.自定义日志文件的名字和位置,记录日志级别
    print(f"{name1}和{name2}正在工作")


learn("Flyme awei")
work('张三', '李四')

在这里插入图片描述

  类实现装饰器有一个优势,在于比嵌套函数的方式更加整洁,而且包裹一个函数还是使用跟以前一样的语法。

相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章
|
20天前
|
开发者 Python
探索Python中的装饰器:从基础到高级应用
本文将带你深入了解Python中的装饰器,这一强大而灵活的工具。我们将一起探讨装饰器的基本概念,它们如何工作,以及如何使用它们来增强函数和类的功能,同时不改变其核心逻辑。通过具体代码示例,我们将展示装饰器的创建和使用,并探索一些高级应用,比如装饰器堆栈和装饰带参数的装饰器。无论你是初学者还是有经验的开发者,这篇文章都将为你提供新的视角,帮助你更有效地使用装饰器来简化和优化你的代码。
|
21天前
|
测试技术 数据安全/隐私保护 开发者
探索Python中的装饰器:从基础到高级应用
装饰器在Python中是一个强大且令人兴奋的功能,它允许开发者在不修改原有函数代码的前提下增加额外的功能。本文将通过具体代码示例,带领读者从装饰器的基础概念入手,逐步深入到高级用法,如带参数的装饰器和装饰器嵌套等。无论你是初学者还是有经验的开发者,这篇文章都将为你提供有价值的见解和技巧。
|
21天前
|
开发框架 数据建模 中间件
Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器是那些静悄悄的幕后英雄。它们不张扬,却能默默地为函数或类增添强大的功能。本文将带你了解装饰器的魅力所在,从基础概念到实际应用,我们一步步揭开装饰器的神秘面纱。准备好了吗?让我们开始这段简洁而富有启发性的旅程吧!
27 6
|
9天前
|
缓存 数据安全/隐私保护 Python
python装饰器底层原理
Python装饰器是一个强大的工具,可以在不修改原始函数代码的情况下,动态地增加功能。理解装饰器的底层原理,包括函数是对象、闭包和高阶函数,可以帮助我们更好地使用和编写装饰器。无论是用于日志记录、权限验证还是缓存,装饰器都可以显著提高代码的可维护性和复用性。
21 5
|
23天前
|
测试技术 Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界中,装饰器是那些能够为我们的代码增添魔力的小精灵。它们不仅让代码看起来更加优雅,还能在不改变原有函数定义的情况下,增加额外的功能。本文将通过生动的例子和易于理解的语言,带你领略装饰器的奥秘,从基础概念到实际应用,一起开启Python装饰器的奇妙旅程。
34 11
|
19天前
|
测试技术 开发者 Python
探索Python中的装饰器:从入门到实践
装饰器,在Python中是一块强大的语法糖,它允许我们在不修改原函数代码的情况下增加额外的功能。本文将通过简单易懂的语言和实例,带你一步步了解装饰器的基本概念、使用方法以及如何自定义装饰器。我们还将探讨装饰器在实战中的应用,让你能够在实际编程中灵活运用这一技术。
37 7
|
19天前
|
Python
探索Python中的装饰器:简化代码,增强功能
在Python的世界里,装饰器就像是给函数穿上了一件神奇的外套,让它们拥有了超能力。本文将通过浅显易懂的语言和生动的比喻,带你了解装饰器的基本概念、使用方法以及它们如何让你的代码变得更加简洁高效。让我们一起揭开装饰器的神秘面纱,看看它是如何在不改变函数核心逻辑的情况下,为函数增添新功能的吧!
|
19天前
|
程序员 测试技术 数据安全/隐私保护
深入理解Python装饰器:提升代码重用与可读性
本文旨在为中高级Python开发者提供一份关于装饰器的深度解析。通过探讨装饰器的基本原理、类型以及在实际项目中的应用案例,帮助读者更好地理解并运用这一强大的语言特性。不同于常规摘要,本文将以一个实际的软件开发场景引入,逐步揭示装饰器如何优化代码结构,提高开发效率和代码质量。
44 6
|
19天前
|
存储 缓存 Python
Python中的装饰器深度解析与实践
在Python的世界里,装饰器如同一位神秘的魔法师,它拥有改变函数行为的能力。本文将揭开装饰器的神秘面纱,通过直观的代码示例,引导你理解其工作原理,并掌握如何在实际项目中灵活运用这一强大的工具。从基础到进阶,我们将一起探索装饰器的魅力所在。
|
19天前
|
测试技术 开发者 Python
深入理解Python装饰器:从基础到高级应用
本文旨在为读者提供一个全面的Python装饰器指南,从其基本概念讲起,逐步深入探讨其高级应用。我们将通过实例解析装饰器的工作原理,并展示如何利用它们来增强函数功能、控制程序流程以及实现代码的模块化。无论你是Python初学者还是经验丰富的开发者,本文都将为你提供宝贵的见解和实用的技巧,帮助你更好地掌握这一强大的语言特性。
30 4