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。
相关推荐
面朝大海,春不暖,花不开5 分钟前
BPF与eBPF简介:核心概念与观测工具概览
开发语言·php·ebpf·bpf·性能观测
ch.ju6 分钟前
Java Programming Chapter 4——Static code block
java·开发语言
弹简特9 分钟前
【Java项目-企悦抽】04-项目演示+项目源码+AI赋能整理接口文档
java·开发语言
郝学胜-神的一滴10 分钟前
Qt 高级编程 034:深耕QWidget底层内核—彻底吃透无边框窗口设计核心原理
开发语言·c++·qt·程序人生·软件开发·用户界面
不会写代码的ys20 分钟前
C++复习篇
java·开发语言·c++
内蒙深海大鲨鱼24 分钟前
数据操作+数据预处理
python
雨师@25 分钟前
go语言项目--实例化(图书管理)--005
开发语言·后端·golang
ai生成式引擎优化技术30 分钟前
从参数驱动到认知行为驱动:SAI范式的理论转向与WSaiOS认知内核架构
python·架构·django·virtualenv·pygame
Aspiresky36 分钟前
探索Rust语言之引用
开发语言·后端·rust
天空'之城40 分钟前
Linux 系统编程 10:线程同步
linux·开发语言·系统编程·线程同步