前端开发入门到精通的在线学习网站

网站首页 > 资源文章 正文

Python快速入门教程11:高级特性之装饰器

qiguaw 2025-03-12 19:57:00 资源文章 78 ℃ 0 评论

一、装饰器简介

装饰器(Decorator)是Python中一种强大的工具,用于修改或增强函数的行为,而不需要直接修改函数的代码。装饰器本质上是一个接受函数作为参数并返回一个新函数的高阶函数。

1. 装饰器的基本结构

装饰器通常定义为一个包裹其他函数的函数,并使用@decorator_name语法糖来应用装饰器。

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

@decorator_function
def display():
    print("这是原始函数")

# 调用被装饰的函数
display()

# 解释:
# - `decorator_function` 是装饰器函数,接受另一个函数作为参数
# - `wrapper_function` 是内部函数,包装了原函数的行为
# - `@decorator_function` 语法糖将 `display` 函数传递给 `decorator_function`
# - `display()` 调用时会先执行 `wrapper_function` 的内容

输出结果:

在原函数之前执行
这是原始函数
在原函数之后执行

二、带参数的装饰器

1. 定义带参数的装饰器

有时我们希望装饰器本身也能接受参数。可以通过再嵌套一层函数来实现。

def decorator_with_arguments(arg1, arg2):
    def decorator_function(original_function):
        def wrapper_function(*args, **kwargs):
            print(f"装饰器参数: {arg1}, {arg2}")
            print("在原函数之前执行")
            result = original_function(*args, **kwargs)
            print("在原函数之后执行")
            return result
        return wrapper_function
    return decorator_function

@decorator_with_arguments("参数1", "参数2")
def display_info(name, age):
    print(f"姓名: {name}, 年龄: {age}")

# 调用被装饰的函数
display_info("Alice", 25)

# 解释:
# - `decorator_with_arguments` 接受装饰器本身的参数
# - `decorator_function` 接受原函数作为参数
# - `wrapper_function` 包装了原函数的行为,并可以访问装饰器参数
# - `@decorator_with_arguments("参数1", "参数2")` 将装饰器应用于 `display_info` 函数

输出结果:

装饰器参数: 参数1, 参数2
在原函数之前执行
姓名: Alice, 年龄: 25
在原函数之后执行

三、类装饰器

1. 使用类作为装饰器

除了函数,类也可以用作装饰器。类装饰器通过实现__call__方法来实现。

class DecoratorClass:
    def __init__(self, original_function):
        self.original_function = original_function

    def __call__(self, *args, **kwargs):
        print("在原函数之前执行")
        result = self.original_function(*args, **kwargs)
        print("在原函数之后执行")
        return result

@DecoratorClass
def display():
    print("这是原始函数")

# 调用被装饰的函数
display()

# 解释:
# - `DecoratorClass` 类实现了 `__call__` 方法,使其可以像函数一样调用
# - `__init__` 方法保存原函数
# - `__call__` 方法包装了原函数的行为
# - `@DecoratorClass` 将类装饰器应用于 `display` 函数

输出结果:

在原函数之前执行
这是原始函数
在原函数之后执行

四、内置装饰器

1.@property

@property 装饰器用于将类的方法转换为只读属性。

class Person:
    def __init__(self, name, age):
        self._name = name
        self._age = age

    @property
    def name(self):
        return self._name

    @property
    def age(self):
        return self._age

    @age.setter
    def age(self, value):
        if value > 0:
            self._age = value
        else:
            raise ValueError("年龄必须大于0")

# 使用 `@property` 装饰器
person = Person("Alice", 25)
print(person.name)  # 输出 Alice
print(person.age)   # 输出 25

person.age = 30
print(person.age)   # 输出 30

# person.age = -1  # 抛出 ValueError

# 解释:
# - `@property` 将方法转换为只读属性
# - `@age.setter` 允许设置属性值,并进行验证

2.@classmethod和@staticmethod

  • @classmethod:将方法绑定到类而不是实例。
  • @staticmethod:将方法定义为静态方法,不接收隐式的第一个参数(如self或cls)。
class MyClass:
    class_variable = "我是类变量"

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

    @classmethod
    def class_method(cls):
        print(f"类方法,访问类变量: {cls.class_variable}")

    @staticmethod
    def static_method():
        print("静态方法,不访问实例或类变量")

# 使用 `@classmethod` 和 `@staticmethod`
MyClass.class_method()  # 输出 类方法,访问类变量: 我是类变量
MyClass.static_method()  # 输出 静态方法,不访问实例或类变量

# 解释:
# - `@classmethod` 绑定到类,可以通过类名调用
# - `@staticmethod` 不依赖于类或实例,可以通过类名或实例调用

五、应用场景

1. 日志记录

装饰器可以用于在函数调用前后记录日志信息。

import logging

def log_decorator(func):
    def wrapper(*args, **kwargs):
        logging.info(f"开始执行函数: {func.__name__}")
        result = func(*args, **kwargs)
        logging.info(f"结束执行函数: {func.__name__}")
        return result
    return wrapper

@log_decorator
def process_data(data):
    print(f"处理数据: {data}")

# 使用日志装饰器
process_data("一些数据")

# 解释:
# - `log_decorator` 记录函数调用的日志
# - `process_data` 函数被装饰后会在执行前后记录日志

2. 性能计时

装饰器可以用于测量函数的执行时间。

import time

def timing_decorator(func):
    def wrapper(*args, **kwargs):
        start_time = time.time()
        result = func(*args, **kwargs)
        end_time = time.time()
        print(f"{func.__name__} 执行时间: {end_time - start_time:.4f} 秒")
        return result
    return wrapper

@timing_decorator
def slow_function():
    time.sleep(2)

# 使用性能计时装饰器
slow_function()

# 解释:
# - `timing_decorator` 测量函数的执行时间
# - `slow_function` 函数被装饰后会在执行前后记录时间

3. 权限验证

装饰器可以用于检查用户权限,确保只有授权用户才能访问某些功能。

def login_required(func):
    def wrapper(user, *args, **kwargs):
        if user.is_authenticated:
            return func(user, *args, **kwargs)
        else:
            print("未授权访问")
    return wrapper

class User:
    def __init__(self, is_authenticated):
        self.is_authenticated = is_authenticated

@login_required
def admin_dashboard(user):
    print("欢迎来到管理员仪表盘")

# 使用权限验证装饰器
user1 = User(is_authenticated=True)
admin_dashboard(user1)  # 输出 欢迎来到管理员仪表盘

user2 = User(is_authenticated=False)
admin_dashboard(user2)  # 输出 未授权访问

# 解释:
# - `login_required` 检查用户是否已登录
# - `admin_dashboard` 函数被装饰后会在执行前进行权限验证

六、总结

装饰器是Python中非常强大的工具,广泛应用于各种编程场景中,例如:

  • 日志记录:在函数调用前后记录日志信息。
  • 性能计时:测量函数的执行时间。
  • 权限验证:确保只有授权用户才能访问某些功能。
  • 缓存:缓存函数的结果以提高性能。
  • 事务管理:确保数据库操作的原子性。

本文暂时没有评论,来添加一个吧(●'◡'●)

欢迎 发表评论:

最近发表
标签列表