- Python教程
- Python 简介
- Python3 下载安装
- python基础语法
- Python基本数据类型
- Python数据类型转换
- Python解释器
- Python 注释
- Python运算符
- Python数字(Number)
- Python字符串
- Python列表
- Python元组
- Python3 字典
- Python集合
- Python条件控制
- Python循环语句
- Python编程第一步
- Python 推导式
- Python3 迭代器与生成器
- Python函数
- Python lambda(匿名函数)
- Python 装饰器
- Python数据结构
- Python3 模块
- Python __name__ 与 __main__
- Python输入和输出
- Python3 File(文件) 方法
- Python3 OS 文件/目录方法
- Python3 错误和异常
- Python3 面向对象
- Python3 命名空间和作用域
- Python3 标准库概览
装饰器(decorators)是 Python 中的一种高级功能,它允许你动态地修改函数或类的行为。
装饰器是一种函数,它接受一个函数作为参数,并返回一个新的函数或修改原来的函数。
装饰器的语法使用 @decorator_name 来应用在函数或方法上。
Python 还提供了一些内置的装饰器,比如 @staticmethod 和 @classmethod,用于定义静态方法和类方法。
装饰器的应用场景:
日志记录: 装饰器可用于记录函数的调用信息、参数和返回值。
性能分析: 可以使用装饰器来测量函数的执行时间。
权限控制: 装饰器可用于限制对某些函数的访问权限。
缓存: 装饰器可用于实现函数结果的缓存,以提高性能。
基本语法
Python 装饰允许在不修改原有函数代码的基础上,动态地增加或修改函数的功能,装饰器本质上是一个接收函数作为输入并返回一个新的包装过后的函数的对象。
语法
def decorator_function(original_function):
def wrapper(*args, **kwargs):
# 这里是在调用原始函数前添加的新功能
before_call_code()
result = original_function(*args, **kwargs)
# 这里是在调用原始函数后添加的新功能
after_call_code()
return result
return wrapper
# 使用装饰器
@decorator_function
def target_function(arg1, arg2):
pass # 原始函数的实现
解析:decorator 是一个装饰器函数,它接受一个函数 func 作为参数,并返回一个内部函数 wrapper,在 wrapper 函数内部,你可以执行一些额外的操作,然后调用原始函数 func,并返回其结果。
decorator_function
是装饰器,它接收一个函数original_function
作为参数。wrapper
是内部函数,它是实际会被调用的新函数,它包裹了原始函数的调用,并在其前后增加了额外的行为。当我们使用
@decorator_function
前缀在target_function
定义前,Python会自动将target_function
作为参数传递给decorator_function
,然后将返回的wrapper
函数替换掉原来的target_function
。
使用装饰器
装饰器通过 @ 符号应用在函数定义之前,例如:
等同于:
这会将 target_function 函数传递给 decorator 装饰器,并将返回的函数重新赋值给 target_function。从而,每次调用 target_function 时,实际上是调用了经过装饰器处理后的函数。
通过装饰器,开发者可以在保持代码整洁的同时,灵活且高效地扩展程序的功能。
以下是一个简单的装饰器示例,它会在函数执行前后打印日志:
实例
def my_decorator(func): def wrapper(): print("在原函数之前执行") func() print("在原函数之后执行") return wrapper @my_decorator def say_hello(): print("Hello!") say_hello()
输出:
my_decorator 是一个装饰器函数,它接受 say_hello 作为参数,并返回 wrapper 函数。
@my_decorator 将 say_hello 替换为 wrapper。
带参数的装饰器
如果原函数需要参数,可以在装饰器的 wrapper 函数中传递参数:
实例
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")
以上代码代码定义了一个装饰器 my_decorator,它会在被装饰的函数执行前后分别打印一条消息。装饰器通过 wrapper 函数包裹原函数,并在调用原函数前后添加额外操作。
输出:
装饰器本身也可以接受参数,此时需要额外定义一个外层函数:
实例
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()
repeat 函数是一个装饰器工厂,它接受一个参数 num_times,返回一个装饰器 decorator。decorator 接受一个函数 func,并返回一个 wrapper 函数。wrapper 函数会调用 func 函数 num_times 次。使用 @repeat(3) 装饰s ay_hell 函数后,调用 say_hello 会打印 "Hello!" 三次。
类装饰器
除了函数装饰器,Python 还支持类装饰器。
类装饰器(Class Decorator)是一种用于动态修改类行为的装饰器,它接收一个类作为参数,并返回一个新的类或修改后的类。
类装饰器可以用于:
添加/修改类的方法或属性
拦截实例化过程
实现单例模式、日志记录、权限检查等功能
类装饰器有两种常见形式:
函数形式的类装饰器(接收类作为参数,返回新类)
类形式的类装饰器(实现 __call__ 方法,使其可调用)
函数形式的类装饰器
以下实例给类添加日志功能:
实例
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()
输出:
类形式的类装饰器(实现 __call__ 方法)
以下实例实现单例模式(Singleton):
实例
class SingletonDecorator: """类装饰器,使目标类变成单例模式""" def __init__(self, cls): self.cls = cls self.instance = None def __call__(self, *args, **kwargs): """拦截实例化过程,确保只创建一个实例""" if self.instance is None: 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,说明是同一个实例
输出:
内置装饰器
Python 提供了一些内置的装饰器,例如:
@staticmethod
: 将方法定义为静态方法,不需要实例化类即可调用。@classmethod
: 将方法定义为类方法,第一个参数是类本身(通常命名为cls
)。@property
: 将方法转换为属性,使其可以像属性一样访问。
实例
class MyClass: @staticmethod def static_method(): print("This is a static method.") @classmethod def class_method(cls): print(f"This is a class method of {cls.__name__}.") @property def name(self): return self._name @name.setter def name(self, value): self._name = value # 使用 MyClass.static_method() MyClass.class_method() obj = MyClass() obj.name = "Alice" print(obj.name)
多个装饰器的堆叠
你可以将多个装饰器堆叠在一起,它们会按照从下到上的顺序依次应用。例如:
实例
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()
输出: