说明Python中装饰器的有用案例
装饰器是一种特殊的函数,它要么接受一个函数并返回一个函数,要么接受一个类并返回一个类。好吧,它可以是任何可调用的(即可以调用的函数、类、方法),它可以返回任何内容,也可以采用方法。这也称为元编程,因为程序的一部分试图在编译时修改程序的另一部分。
让我们深入研究Python装饰器并找出它们可以做什么。这不会涵盖基础知识或带有参数的装饰器,而是一些有用的示例来说明这种情况。
Refer the below article to get the basics of Python decorators
- Python decorators
基本上,装饰器接受一个可调用对象,任何实现特殊方法__call()__
的对象都被称为可调用对象,添加一些功能并返回一个可调用对象。
示例 1:
# Python program to demonstrate
# decorators
# Creating a decorator
def decorated_func(func):
def inner():
print("This is decorated function")
func()
return inner()
def ordinary_func ():
print("This is ordinary function")
decorated = decorated_func(ordinary_func)
decorated
输出:
This is decorated function
This is ordinary function
在上面显示的示例中, decorated_func()
是一个装饰器。简而言之,装饰器充当包装对象(不改变原始对象)并向原始对象添加新功能的包装器。这是一个常见的结构,所以Python有一个语法特性(称为Decorator
)来简化它。例如,
这:
@decorated_func
def ordinary_func():
print("This is ordinary function")
相当于:
def ordinary_func():
print("This is ordinary function")
decorated = decorated_func(ordinary_func)
一个简单的例子是:
示例 2:
输入:
def mul_decorator(func):
def wrapper(*args, **kwargs):
print('function', func.__name__, 'called with args - ', /
args, 'and kwargs - ', kwargs)
result = func(*args, **kwargs)
print('function', func.__name__, 'returns', result)
return result
return wrapper
@mul_decorator
def mul(a, b):
return a * b
mul(3, 3)
mul(3, b = 6)
输出:
function mul called with args - (3, 3) and kwargs - {}
function mul returns 9
function mul called with args - (3,) and kwargs - {'b': 6}
function mul returns 18
您还可以将内置插件用作装饰器
示例 3:
# func will be func = type(func) ->
@type
def func():
return 42
print(func)
# print doesn't return anything, so func == None
@print
def func2():
return 42
# Prints None
print(func2)
输出:
None
您可以用其他东西替换装饰对象
示例 4:
# Creating a decorator
class function_1:
def __init__(self, func):
self.func = func
self.stats = []
def __call__(self, *args, **kwargs):
try:
result = self.func(*args, **kwargs)
except Exception as e:
self.stats.append((args, kwargs, e))
raise e
else:
self.stats.append((args, kwargs, result))
return result
@classmethod
def function_2(cls, func):
return cls(func)
@function_1.function_2
def func(x, y):
return x / y
print(func(6, 2))
print(func(x = 6, y = 4))
func(5, 0)
print(func.stats)
print(func)
输出:
3.0
1.5
Traceback (most recent call last):
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 29, in
func(5, 0)
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 11, in __call__
raise e
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 8, in __call__
result = self.func(*args, **kwargs)
File "/home/1ba974e44c61e303979b3ee120b6b066.py", line 23, in func
return x / y
ZeroDivisionError: division by zero
请注意原来的"func"
是如何被"function_1"
的一个实例替换的,它的使用方式与原来的函数相同。
您可以与系统中的其他对象创建关系
示例 5:
def dict_from_func(func):
return {func.__name__: func}
activity = {}
@activity.update
@dict_from_func
def mul(a, b):
return a * b
@activity.update
@dict_from_func
def add(a, b):
return a + b
print(mul)
print(activity)
print(activity['mul'](2, 5))
输出:
None
{'mul': ,
'add': }
10
在这里,在示例 5 中,我们使用了dict.update
方法作为装饰器,即使它不是为此而设计的。这是可能的,因为dict_from_func
返回一个字典,而dict.update
将一个字典作为参数。
实际上,这个:
@activity.update
@dict_from_func
def mul(a, b):
return a * b
等于——
def mul(a, b):
return a * b
mul = activity.update(dict_from_func(mul))
结论
装饰器是一个有趣且令人惊叹的功能,可用于多种用途。它不仅仅是“接受函数或类并返回函数或类的函数或类” 。