python 装饰器

欢迎访问我的博客首页。


装饰器

  • [1. 函数装饰函数](#1. 函数装饰函数)
    • [1.1 基础装饰器](#1.1 基础装饰器)
    • [1.2 装饰器工厂](#1.2 装饰器工厂)
  • [2. 函数装饰类](#2. 函数装饰类)
  • [3. 类装饰函数](#3. 类装饰函数)
  • [4. 类装饰类](#4. 类装饰类)
  • [5. 参考](#5. 参考)

1. 函数装饰函数


  用函数装饰函数的装饰器。

1.1 基础装饰器


  下面定义一个名为 decorator 的装饰器。functools.wraps 用于还原函数名。

python 复制代码
import functools

def decorator(func):
    @functools.wraps(func)
    def wrapper(*args, **kwargs):
        print('original func name:', func.__name__)
        return func(*args, **kwargs)

    return wrapper

  下面是使用装饰器 decorator 装饰函数 test1_1 和 test1_2 的例子。

python 复制代码
@decorator
def test1_1():
    return 'hello world1_1'

def test1_2():
    return 'hello world1_2'

test1_2 = decorator(test1_2)

if __name__ == '__main__':
    print(test1_1())
    print()
    print(test1_2())

  装饰函数的函数,可以预处理被装饰函数的参数。基于 python 的 web 应用程序的后端框架经常用这样的装饰器作为登录验证,比如 flask 框架。

1.2 装饰器工厂


  下面是带参数的装饰器及其用法。

python 复制代码
def decorator_factor(param=0):
    def decorator(func):
        @functools.wraps(func)
        def wrapper(*args, **kwargs):
            print('original func name:', func.__name__)
            print('param:', param)
            return func(*args, **kwargs)

        return wrapper

    return decorator

@decorator_factor(param=2)
def test2():
    return 'hello world2'
    
if __name__ == '__main__':
    print(test2())

  装饰器工厂用于控制被装饰函数的执行次数,以及统计被装饰函数的耗时等。

2. 函数装饰类


  用函数装饰类的装饰器,以单例模式为例。

python 复制代码
def singleton(cls):
    instance = {}

    def create(*args, **kwargs):
        if cls not in instance:
            param = args[0]
            instance[cls] = cls(param + 1)
        return instance[cls]

    return create

@singleton
class Example:
    def __init__(self, x):
        print('--构造函数, x=', x)

    def __del__(self):
        print('--析构函数')

if __name__ == '__main__':
    a = Example(1)
    b = Example(1)
    print(id(a))
    print(id(b))

  装饰类的函数,可以预处理被装饰类的构造函数的参数,也可以控制被装饰函数的对象的创建。

3. 类装饰函数


  用类装饰函数的装饰器。

python 复制代码
class Decorator:
    def __init__(self, func):
        self.func = func

    def __call__(self, *args, **kwargs):
        param = args[0]
        param += 1
        return self.func(param)

@Decorator
def fac(param):
    return param

if __name__ == '__main__':
    print(fac(1))

  装饰函数的类,可以预处理被装饰函数的参数。

4. 类装饰类


  用类装饰类的装饰器,以单例模式为例。

python 复制代码
class Singleton:
    instance = None

    def __init__(self, cls):
        self.cls = cls

    def __call__(self, *args, **kwargs):
        if not self.instance:
            self.instance = self.cls(*args, **kwargs)
        return self.instance

@Singleton
class Example:
    def __init__(self):
        print('--构造函数')

    def __del__(self):
        print('--析构函数')

if __name__ == '__main__':
    a = Example()
    b = Example()
    print(id(a))
    print(id(b))

  装饰类的类,可以预处理被装饰类的构造函数的参数,也可以控制被装饰函数的对象的创建。

5. 参考


  1. 装饰器工厂,CSDN,2022。
  2. python 单例模式,CSDN,2023。
  3. 函数与类相互装饰,CSDN,2023。
相关推荐
1024奇点8 小时前
【仓颉语言入门 · 第二篇 第 22 课】
开发语言·ide·开源
实名上网宋凯宣8 小时前
Django
后端·python·django
Warren2Lynch9 小时前
C4 模型详解:利用 Visual Paradigm 可视化软件架构的综合指南
开发语言·uml
如若12310 小时前
【论文复现】CoFailMed:从零复现医学图像分割的共享失败审计,含完整代码流程与科研绘图
人工智能·python
Knight_AL10 小时前
Java 文件下载时文件名中的 `#` 被转换成 `%23`?一次 URL 编码与解码问题排查
java·开发语言
FRing0310 小时前
vue2干货总结2(v-bind、v-for、v-model、指令修饰符、v-bind操作class和style)
开发语言·前端·vue.js·vue2
by2099911 小时前
C++ 智能指针的所有权与使用
开发语言·c++·经验分享
砚底藏山河11 小时前
python量化自定义周期 K 线合成
java·开发语言·数据库·python·金融
视觉小萌新11 小时前
AI Class 3 · Chapter 1:变量、字符串、list/dict、if/for(python学习-小白版-有经验可跳过)
python·学习·list
IT召唤狮11 小时前
开源企业级零信任项目Pangolin,零信任能挡住PHP核弹漏洞吗?
开发语言·开源·php