介绍
函数装饰器是Python中一种强大的工具,它可以用来修改或增强函数的行为。通常函数装饰器用于装饰函数,但是也可以使用它来装饰类。因此可以使用它修改类的构造函数、添加类属性或方法,或者对类的行为进行其他定制化的操作。
分类
1,无参装饰器
def decorator(cls):
# 定义一个新的类,继承自原始的类
class Wrapper(cls):
def __init__(self, *args, **kwargs):
# 在构造函数中可以添加自定义逻辑
print("CallMe之前执行")
super().__init__(*args, **kwargs)
print("CallMe之后执行")
return Wrapper
@decorator
class CallMe(object):
def __init__(self, name, phone):
self.name = name
self.phone = phone
print("我被执行了!")
def call_me(self):
print(f"名字:{self.name},电话:{self.phone}")
call = CallMe("萧炎", "9090")
输出:
CallMe之前执行
我被执行了!
CallMe之后执行
decorator
函数是一个函数装饰器,它接受一个类作为被装饰对象,并返回一个新的类 Wrapper
,该类继承自被装饰的类 cls
。在 Wrapper
的构造函数中,我们添加了两条打印语句,以便在创建类的实例时显示消息。
然后使用 @decorator
装饰器语法来装饰 CallMe
类,使其成为装饰后的类。当创建 CallMe
的实例时,会首先调用 Wrapper
的构造函数。
2,有参装饰器
def decorator(arg1):
def rapper(cls):
# 定义一个新的类,继承自原始的类
class Inner(cls):
def __init__(self, *args, **kwargs):
print("CallMe之前执行")
super().__init__(*args, **kwargs)
# 在构造函数中可以使用参数 arg1
self.name = arg1
print("CallMe之后执行")
return Inner
return wrapper
# 使用带参数的装饰器来装饰一个类
@decorator("云韵")
class CallMe(object):
def __init__(self, name, phone):
self.name = name
self.phone = phone
print("我被执行了!")
def call_me(self):
print(f"名字:{self.name},电话:{self.phone}")
call = CallMe("萧炎", "9090")
call.call_me()
输出:
CallMe之前执行
我被执行了!
CallMe之后执行
名字:云韵,电话:9090
decorator
函数是一个带参数的函数装饰器,它接受参数 arg1
。然后,它返回一个内部装饰器函数 wrapper
,这个函数接受一个类作为被装饰对象,并返回一个新的类 Inner
。
在 Inner
的构造函数中可以访问参数 arg1
,并在创建类的实例时使用它。最后使用 @decorator("arg1_value")
来装饰 CallMe
,传递参数给装饰器。
当创建 CallMe
的实例时,会首先调用 Inner
的构造函数,更新self.name
的值。
3,原始写法
from functools import wraps
def logit(func):
@wraps(func)
def wrapper(*args, **kwargs):
print('-' * 10)
print('Calling: ' + func.__name__)
value = func(*args, **kwargs)
print('-' * 10)
return value
return wrapper
@logit
class Tester():
def __init__(self):
print('__init__ ended')
def a_func(self):
print('a_func ended')
tester = Tester()
tester.a_func()
输出:
----------
Calling: Tester
__init__ ended
----------
a_func ended
总结
可以根据需求在装饰器中添加更复杂的逻辑,以修改类的行为。
函数装饰器为类提供了更灵活的定制选项,可以根据需求对类进行扩展和修改。
带参数的函数装饰器可以根据需要在装饰器和装饰的类之间传递不同的参数来实现更多的定制化。