用 Python 装饰器为代码加分:函数与类行为的灵活控制

装饰器是 Python 中的一个高级特性,它通过允许你动态地扩展或修改函数、方法或类的行为,极大地提升了代码的可重用性和模块化。理解装饰器的工作原理,能够帮助你写出更简洁、高效、可维护的代码。

1. 什么是装饰器?

在 Python 中,装饰器本质上是一个函数,它接受另一个函数作为输入,经过加工后返回一个新的函数(或修改过的函数)。装饰器通常用于扩展或修改函数的功能,而无需修改原函数的源代码。

装饰器的常见用途包括:

  • 日志记录:自动记录函数调用的输入输出信息。
  • 性能分析:测量函数执行时间,优化性能。
  • 权限控制:限制函数的访问权限,增加安全性。
  • 缓存:缓存函数结果以提高性能。

那么就需要问问各位懂行大佬!!!
哪些情况使用装饰器会比较好!!!
希望评论留言!!!

2. 装饰器的基本语法

装饰器的基本语法非常简洁,使用 @decorator_name 语法来应用装饰器。

def decorator_function(original_function):
    def wrapper(*args, **kwargs):
        print("函数执行前的操作")
        result = original_function(*args, **kwargs)
        print("函数执行后的操作")
        return result
    return wrapper

@decorator_function
def target_function(arg1, arg2):
    print(f"原始函数执行,参数为:{arg1}, {arg2}")

在上述代码中,@decorator_functiontarget_function 作为参数传递给装饰器 decorator_function,并将返回的 wrapper 函数替代原函数。

看过一篇文章中的等价关系:

3. 一个简单的装饰器实例

以下是一个简单的装饰器示例,在函数执行前后打印日志:

def my_decorator(func):
    def wrapper():
        print("在函数之前执行")
        func()
        print("在函数之后执行")
    return wrapper

@my_decorator
def say_hello():
    print("Hello!")

say_hello()

输出为:

4. 带参数的装饰器

如果目标函数需要参数,你可以通过在 wrapper 函数中使用 *args**kwargs 来传递这些参数:

def my_decorator(func):
    def wrapper(*args, **kwargs):
        print("函数执行前")
        func(*args, **kwargs)
        print("函数执行后")
    return wrapper

@my_decorator
def greet(name):
    print(f"Hello, {name}!")

greet("Alice")

输出为:


5. 带参数的装饰器工厂

装饰器本身也可以接受参数。如果你希望控制装饰器的行为,可以通过创建装饰器工厂来接受参数。例如,以下装饰器会让函数重复执行多次:

def repeat(num_times):
    def decorator(func):
        def wrapper(*args, **kwargs):
            for _ in range(num_times):
                func(*args, **kwargs)
        return wrapper
    return decorator

@repeat(3)
def say_hello():
    print("Hello!")

say_hello()

输出为:


6. 类装饰器:动态修改类行为

除了函数装饰器,Python 也支持类装饰器。类装饰器用于修改类的行为,它接收一个类作为参数,并返回修改后的类。类装饰器常见的应用场景包括实现单例模式、日志记录等。

6.1 函数形式的类装饰器

下面是一个类装饰器的例子,它在类方法执行前后打印日志:

def log_class(cls):
    class Wrapper:
        def __init__(self, *args, **kwargs):
            self.wrapped = cls(*args, **kwargs)
        def __getattr__(self, name):
            return getattr(self.wrapped, name)
        def display(self):
            print(f"调用 {cls.__name__}.display() 前")
            self.wrapped.display()
            print(f"调用 {cls.__name__}.display() 后")
    return Wrapper

@log_class
class MyClass:
    def display(self):
        print("这是 MyClass 的 display 方法")

obj = MyClass()
obj.display()

输出为:

6.2 类形式的类装饰器(单例模式)

类装饰器还可以用于实现单例模式,确保类的实例是唯一的:

class SingletonDecorator:
    def __init__(self, cls):
        self.cls = cls
        self.instance = None

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

@SingletonDecorator
class Database:
    def __init__(self):
        print("Database 初始化")

db1 = Database()
db2 = Database()
print(db1 is db2)  # True,说明是同一个实例

输出为:


7. Python 内置装饰器

Python 提供了几个常用的内置装饰器,帮助开发者更加高效地管理类和函数。

  • @staticmethod:定义静态方法,无需实例化类即可调用。
  • @classmethod:定义类方法,接收类本身作为第一个参数。
  • @property:将方法转换为属性访问。

8. 多个装饰器的堆叠

你还可以将多个装饰器堆叠在一起,它们会按照从下到上的顺序依次应用:

def decorator1(func):
    def wrapper():
        print("Decorator 1")
        func()
    return wrapper

def decorator2(func):
    def wrapper():
        print("Decorator 2")
        func()
    return wrapper

@decorator1
@decorator2
def say_hello():
    print("Hello!")

say_hello()

输出为:


这里疑惑为什么 Decorator 1 后面没有 Hello! 呢???

实际输出如图片所示!!!分享

结语

装饰器是 Python 中非常强大的功能之一,它允许你在不修改原始代码的前提下,为函数或类动态添加新行为。通过理解装饰器的使用方法,你可以在工作中更加灵活地应对各种需求,从日志记录到性能优化,装饰器都是你得心应手的工具。

有什么不对的地方还请各位大哥批评指正!!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值