# 装饰器:函数作为装饰器参数,在导入模块时候执行装饰器函数
# 函数装饰器
if 0:
def register(func):
return func
@register
def test1(name, age):
print(name, age)
@register
def test2(*args, **kwargs):
print(args, kwargs)
test1("zhangsan", 10)
test2("a", "b", name="zhangsan", age=20)
# 有时候需要对函数做额外的操作,这就需要用到函数闭包
if 1:
def register(func):
# 装饰器中有定义一个函数并返回,可以做其他动作
def decorator(*args, **kwargs):
print("begin", func.__name__)
func(*args, **kwargs)
print("end", func.__name__)
return decorator
@register
def test1(name, age):
print(name, age)
@register
def test2(*args, **kwargs):
print(args, kwargs)
test1("zhangsan", 20)
test2("a", "b", name="zhangsan", age=20)
# 若装饰器函数需要传入参数,用于不同逻辑处理呢,再包裹一层
if 1:
def register(num):
# _register做为函数对象返回
def _register(func):
def decorator(*args, **kwargs):
if num:
print("begin", func.__name__)
func(*args, **kwargs)
print("end", func.__name__)
return decorator
return _register
@register(0)
def test1(name, age):
print(name, age)
@register(1)
def test2(*args, **kwargs):
print(args, kwargs)
test1("zhangsan", 20)
test2("a", "b", name="zhangsan", age=20)
if 0:
# 函数装饰器装饰类,可以为类添加些类属性
def decorator(cls):
cls.name = "10"
return cls
@decorator
class Test:
def test(self):
print(f"{self.test.__func__}")
t = Test() # 相当于 t = decorator(Test)
print(t.name)
# 10
if 0:
# 函数装饰器装饰类,传入参数,参数可以作为类属性
def decorator(func):
def wrapper(cls):
func("exec func")
cls.name = "10"
cls.func = func
return cls
return wrapper
def test_print(*arg):
print(arg)
@decorator(test_print) # 类装饰器传参数
class Test:
def test(self):
print("exec test")
self.func("exec func in test")
t = Test()
# ('exec func',)
print(t.name)
# 10
Test.func("use Test class exec func")
# ('use Test class exec func',)
t.func("use Test instance exec func")
# (<__main__.Test object at 0x0000029098443C70>, 'use Test instance exec func'), 打印两个是因为第一个参数有实例self
t.test()
# exec test
# (<__main__.Test object at 0x0000029098443C70>, 'exec func in test'), 第一个参数是self
if 0:
# 函数装饰器用于装饰类的成员方法
def register(func):
return func
# 函数装饰器装饰类成员方法,该方法带有参数
def register_with_arg(func):
def decorator(*arg, **kwargs):
func(*arg, **kwargs)
return decorator
class Test:
@register
def test(self):
print("exec test")
@register_with_arg
def test_with_arg(self, *arg, **kwargs):
print("exec test_with_arg")
t = Test()
t.test()
# exec test
t.test_with_arg()
# exec test_with_arg
if 1:
# 静态方法和类方法作为函数装饰器,可以装饰外部函数,外部类和内部类成员函数
class Test:
NAME="zhangsan"
# 静态方法作为装饰器函数,用法和普通装饰器函数一样,没有区别
@staticmethod
def test_static(func):
def decorator(*arg, **kwargs):
func(*arg, **kwargs)
return decorator
# 类方法作为装饰器函数,可以用类属性
@classmethod
def test_class(cls, func):
def decorator(*arg, **kwargs):
print(cls.NAME)
func(*arg, **kwargs)
return decorator
# 类方法作为装饰器函数装饰类, 第一个cls1是Test类,cls2是被装饰类
@classmethod
def test_class_decorator_class(cls1, cls2):
def decorator(*arg, **kwargs):
print(cls1.NAME)
return cls2
return decorator
@test_static #使用类静态成员方法装饰该类的实例成员方法,不要加上Test,因为该类还没有定义完,所以会报undefined
def test_method(self, *arg, **kwargs):
print(arg, kwargs)
@Test.test_static
def external_static_func(*arg, **kwargs):
print(arg, kwargs)
@Test.test_class
def external_class_func(*arg, **kwargs):
print(arg, kwargs)
@Test.test_class_decorator_class
class MyTest:
def test():
print("exec MyTest.test")
external_static_func("hello", "world")
# ('hello', 'world') {}
external_class_func("hello", "zhangsan")
# zhangsan
# ('hello', 'zhangsan') {}
t = MyTest()
t.test()
# zhangsan
# exec MyTest.test
ts = Test()
ts.test_method("lisi")
# ('lisi',) {}
ts.test_method1("wangwu")
# ('wangwu',) {}
if 1:
# 类作为装饰器
class Test:pass
python 装饰器使用
于 2024-11-27 22:41:06 首次发布