假设我们想为已经编写的代码添加额外的功能,例如我们想在一个特殊的 try catch 块中捕获任何错误,我们可以按如下方式进行。
def some_decorator(func): def try_except_block(*args, **kwargs): 尝试: func(*args, **kwargs) 除了例外: 打印(例外) 返回 try_except_block[ @some_decorator](https://twitter.com/some_decorator) def some_function(): 打印(“你好世界”) 一些函数()
这里 some_decorator 是一个修饰函数,它修改了 some_function 的行为。如您所见,由于我们使用 *args、**kwargs,因此对 some_function 的参数没有限制。
还有另一种实现装饰器的方法。让我们看下面的示例来计算函数运行所花费的时间。
从 ast 导入 arg 进口时间 导入数学 def some_decorator(func): def time_taken_block(*args, **kwargs): begin_time = time.time() func(*args, **kwargs) end_time = time.time() print("", func.__name__, " is ", end_time - begin_time) 返回 time_taken_block def some_function(): 时间.sleep(2) 打印(“你好世界”) some_function = some_decorator(some_function) 一些函数()
这里不是在我们要运行的函数的顶部指定装饰器,而是通过将其插入到装饰器函数中并调用修改后的函数来修改函数调用。
但是,对于最佳编码实践,请使用以前的方法,因为它更容易追溯。如果您在以前的方法中使用上述方法,您可能会遇到以下问题。
进口时间 def some_decorator(func): def time_taken_block(*args, **kwargs): begin_time = time.time() func(*args, **kwargs) end_time = time.time() print("花费的总时间", func.__name__, "is", end_time - begin_time) 返回 time_taken_block[ @some_decorator](https://twitter.com/some_decorator) def some_function(): """睡两秒钟。""" 时间.sleep(2) 打印(“你好世界”) 一些函数() 打印(some_function.__name__) 打印(some_function.__doc__) # 你好世界 # some_function 花费的总时间是 2.0111606121063232 # time_taken_block # 没有任何
这里函数名和文档被装饰器替换,为了解决这个问题,我们使用 functools 包装函数并传递装饰函数名。
导入功能工具 进口时间 def some_decorator(func): [ @functools](https://twitter.com/functools) .wraps(函数) def time_taken_block(*args, **kwargs): begin_time = time.time() func(*args, **kwargs) end_time = time.time() print("花费的总时间", func.__name__, "is", end_time - begin_time) 返回 time_taken_block[ @some_decorator](https://twitter.com/some_decorator) def some_function(): """睡两秒钟。""" 时间.sleep(2) 打印(“你好世界”) 一些函数() 打印(some_function.__name__) 打印(some_function.__doc__) # 你好世界 # some_function 花费的总时间是 2.00304913520813 # some_function # 休眠两秒。
版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明
本文链接:https://www.qanswer.top/18618/46410609