【python】装饰器
装饰器
- python 语法特性,允许在不修改原函数代码的情况下,为函数添加新的功能
- 接受一个函数作为参数,并返回一个新的函数
1. 装饰器表示方法
@装饰器函数
多个装饰器可以叠加使用
2. 装饰器类型
2.1 函数装饰器
2.1.1 基本函数装饰器
'''
将参数在装饰器中先执行,再利用执行后的结果做一些判断处理等
'''
def my_decorator(func):print("This is my_decorator")def wrapper():print("参数函数执行前")func()print("参数函数执行后")return wrapper@my_decorator
def my_func():print("This is my_func")my_func()
输出:
This is my_decorator
参数函数执行前
This is my_func
参数函数执行后
2.1.2 带参数的函数装饰器
函数带参数
def my_decorator2(func):print("This is test_1")def decorator(*args):print("args:", args) #(1,2,'a')func(*args)return decorator @my_decorator2
def my_func2(a,b,s):print("This is test_func")my_func2(1,2,'a')
装饰器与函数都带参数
def my_decorator3(param=None):print("This is my_decorator2, param:", param) #123def decorator(func):def wrapper(*args, **kwargs):print("参数函数执行前")print("传入参数:", args, kwargs) #(1,2) {'key':'value'}func(args, kwargs)print("参数函数执行后")return wrapperreturn decorator@my_decorator3(123) # 装饰器自身参数
def my_func3(*args, **kwargs):print("This is my_func2:", args, kwargs)my_func3(1, 2, key='value')
2.2 类装饰器
类作为装饰器
2.2.1 不带参数
'''
function timer 装饰器: 计算func函数执行时间
'''
class MyTimer:def __init__(self, func):self.func = funcdef __call__(self, *args, **kwargs):import timestart = time.time()result = self.func(*args, **kwargs)end = time.time()print(f"Function {self.func.__name__} took {end - start:.4f} seconds to execute.") # 运行函数锁花费的时间return result@MyTimer
def compute_square(n):total = 0for i in range(n):total += i * iprint("i:", i)print("total:", total)return totalcompute_square(3)
2.2.2 带参数
class Logger:def __init__(self, level="INFO"):self.level = leveldef __call__(self, func):def wrapper(*args, **kwargs):print(f"[{self.level}] Calling function: {func.__name__}")return func(*args, **kwargs) # 在调用带装饰器的函数时执行并返回结果return wrapper #在@装饰器应用时返回@Logger(level="DEBUG")
def sample_function(x, y):return x + y
2.3 方法装饰器(修饰类方法的装饰器)
def class_decorator(cls):def wrapper(*args, **kwargs):print(f"Creating instance of {cls.__name__} with args: {args}, kwargs: {kwargs}")instance = cls(*args, **kwargs)print(1111111111)return instanceprint(22222222)return wrapperclass MyClass:@class_decoratordef my_method(self):print("MyClass method called")cls = MyClass()
cls.my_method()'''
22222222
===main==
Creating instance of my_method with args: (<__main__.MyClass object at 0x7f1eca099790>,), kwargs: {}
MyClass method called
1111111111
yh@ubuntu:~/y
'''
2.4 内置装饰器(修饰类内部方法的装饰器)
2.4.1 @staticmethod
不用创建实例即可调用
class MyClass_test:@staticmethoddef my_func(): # 不带self参数,不需要通过具体实例调用print("MyClass method2 called")MyClass_test.my_func()
2.4.2 @classmethod
通过类直接调用
class MyClass:g_counter = 0def __init__(self):MyClass.g_counter += 1@classmethoddef get_instance_count(cls):return cls.g_counterMyClass.get_instance_count()
2.4.3
像访问属性一样使用
class Circle:def __init__(self, radius):self._radius = radius@propertydef radius(self):return self._radius@radius.setterdef radius(self, value):if value < 0:raise ValueError("Radius cannot be negative")self._radius = value@propertydef area(self):return 3.14159 * (self._radius ** 2)cir = Circle(5)print("Radius:", cir.radius) # 像属性一样访问print ("Area:", cir.area)cir.radius = 10 # 使用setter方法更新半径print("Updated Radius:", cir.radius)
3 装饰器作用
- 代码复用
- 函数之前前条件验证
