自学内容网 自学内容网

深入理解 Python 的装饰器

💖 欢迎来到我的博客! 非常高兴能在这里与您相遇。在这里,您不仅能获得有趣的技术分享,还能感受到轻松愉快的氛围。无论您是编程新手,还是资深开发者,都能在这里找到属于您的知识宝藏,学习和成长。

🔍 博客内容包括:

  • Java核心技术与微服务:涵盖Java基础、JVM、并发编程、Redis、Kafka、Spring等,帮助您全面掌握企业级开发技术。
  • 大数据技术:涵盖Hadoop(HDFS)、Hive、Spark、Flink、Kafka、Redis、ECharts、Zookeeper等相关技术。
  • 开发工具:分享常用开发工具(IDEA、Git、Mac、Alfred、Typora等)的使用技巧,提升开发效率。
  • 数据库与优化:总结MySQL及其他常用数据库技术,解决实际工作中的数据库问题。
  • Python与大数据:专注于Python编程语言的深度学习,数据分析工具(如Pandas、NumPy)和大数据处理技术,帮助您掌握数据分析、数据挖掘、机器学习等技术。
  • 数据结构与算法:总结数据结构与算法的核心知识,提升编程思维,帮助您应对大厂面试挑战。

🌟 我的目标:持续学习与总结,分享技术心得与解决方案,和您一起探索技术的无限可能!在这里,我希望能与您共同进步,互相激励,成为更好的自己。

📣 欢迎订阅本专栏,与我一起在这个知识的海洋中不断学习、分享和成长!💻🚀


📍版权声明:本博客所有内容均为原创,遵循CC 4.0 BY-SA协议,转载请注明出处。

目录

一、什么是装饰器?

二、简单的装饰器示例

示例 1:打印日志

三、装饰器的原理

1. 函数即对象

2. 闭包

四、装饰器的高级用法

1. 为装饰器传递参数

2. 保留原函数的元数据

3. 装饰类方法

五、内置装饰器

1. @staticmethod

2. @classmethod

3. @property

六、多个装饰器的执行顺序

七、常见的装饰器应用场景

1. 权限验证

2. 性能分析


装饰器是 Python 中非常强大和灵活的功能。它可以在不改变函数定义的情况下,动态地为函数或方法添加新的功能。本文将带你深入理解装饰器的原理、用法以及一些高级技巧。


一、什么是装饰器?

装饰器本质上是一个函数,它接收一个函数作为参数,并返回一个增强后的函数。装饰器通常用来修改函数的行为,比如增加日志记录、访问控制或性能计时等。

装饰器的基本语法:

@decorator_function
def original_function():
    pass

 等价于:

def original_function():
    pass

original_function = decorator_function(original_function)

二、简单的装饰器示例

示例 1:打印日志
def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Calling function '{func.__name__}' with arguments {args} and {kwargs}")
        result = func(*args, **kwargs)
        print(f"Function '{func.__name__}' returned {result}")
        return result
    return wrapper

@logger
def add(a, b):
    return a + b

add(3, 5)

输出:

Calling function 'add' with arguments (3, 5) and {}
Function 'add' returned 8

三、装饰器的原理

1. 函数即对象

在 Python 中,函数是一等公民,可以作为参数传递,也可以作为返回值。

2. 闭包

装饰器通常依赖闭包来保存上下文信息。闭包是指在嵌套函数中,内部函数引用了外部函数的变量。

示例:

def outer_function(message):
    def inner_function():
        print(message)
    return inner_function

closure = outer_function("Hello, World!")
closure()

输出:

Hello, World!

四、装饰器的高级用法

1. 为装饰器传递参数

如果需要给装饰器传递参数,可以使用多层嵌套。

示例:

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

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

greet("Alice")

输出:

Hello, Alice!
Hello, Alice!
Hello, Alice!
2. 保留原函数的元数据

使用 functools.wraps 可以保留被装饰函数的原始信息(如名称和文档字符串)。

示例:

from functools import wraps

def logger(func):
    @wraps(func)
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

@logger
def add(a, b):
    """Add two numbers."""
    return a + b

print(add.__name__)
print(add.__doc__)

输出:

add
Add two numbers.
3. 装饰类方法

装饰器也可以用于类方法。

示例:

def logger(func):
    def wrapper(*args, **kwargs):
        print(f"Calling {func.__name__}")
        return func(*args, **kwargs)
    return wrapper

class MyClass:
    @logger
    def greet(self):
        print("Hello from MyClass!")

obj = MyClass()
obj.greet()

输出:

Calling greet
Hello from MyClass!

五、内置装饰器

Python 提供了一些常用的内置装饰器:

1. @staticmethod

定义类的静态方法,与类实例无关。

class MyClass:
    @staticmethod
    def static_method():
        print("This is a static method.")

MyClass.static_method()
2. @classmethod

定义类方法,可以访问类本身。

class MyClass:
    @classmethod
    def class_method(cls):
        print(f"This is a class method from {cls}.")

MyClass.class_method()
3. @property

将方法变为属性。

class MyClass:
    def __init__(self, name):
        self._name = name

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

obj = MyClass("Alice")
print(obj.name)

六、多个装饰器的执行顺序

当一个函数有多个装饰器时,它们的执行顺序是自下而上。

示例:

def decorator1(func):
    def wrapper(*args, **kwargs):
        print("Decorator 1")
        return func(*args, **kwargs)
    return wrapper

def decorator2(func):
    def wrapper(*args, **kwargs):
        print("Decorator 2")
        return func(*args, **kwargs)
    return wrapper

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

greet()

输出:

Decorator 1
Decorator 2
Hello!

七、常见的装饰器应用场景

1. 权限验证
def requires_permission(permission):
    def decorator(func):
        def wrapper(user, *args, **kwargs):
            if user.has_permission(permission):
                return func(user, *args, **kwargs)
            else:
                print("Permission denied!")
        return wrapper
    return decorator

@requires_permission("admin")
def delete_user(user, username):
    print(f"User {username} deleted.")
2. 性能分析
import time

def timer(func):
    def wrapper(*args, **kwargs):
        start = time.time()
        result = func(*args, **kwargs)
        end = time.time()
        print(f"{func.__name__} executed in {end - start:.2f} seconds")
        return result
    return wrapper

@timer
def compute():
    time.sleep(2)
    print("Computation done!")

compute()


原文地址:https://blog.csdn.net/weixin_45710998/article/details/145136771

免责声明:本站文章内容转载自网络资源,如本站内容侵犯了原著者的合法权益,可联系本站删除。更多内容请关注自学内容网(zxcms.com)!