当前位置: 首页 > 后端技术 > Python

翻译:《实用的Python编程》07_04_Function_decorators

时间:2023-03-25 22:36:22 Python

上一节(7.3返回函数)|下一节(7.5装饰方法)7.4函数装饰器本节介绍装饰器。因为这是一个高级主题,我们只会简要介绍它。译注:根据译者个人的猜测,在《设计模式》(《 Design Patterns: Elements of Reusable Object-Oriented Software》)一书中写到装饰器又称为包装器,所以下面提到包装器(wrapper),其实就是装饰器。这里为了与原文保持一致,翻译时没有将“wrapper”替换为“decorator”。日志示例考虑这样一个函数:defadd(x,y):returnx+y考虑在add(x,y)函数中添加日志函数:defadd(x,y):print('Callingadd')returnx+y也有一个带有日志记录的sub(x,y)函数:defsub(x,y):print('Callingsub')returnx-yObservationObservation:Thisisarepetition.在有很多重复代码的地方编写程序通常很烦人。这些代码不仅写起来枯燥乏味,而且维护起来也很麻烦。特别是如果您决定改变它的工作方式(例如,可能是另一种类型的日志记录)。日志记录代码也许您可以创建一个函数来添加日志记录功能。例如包装器:deflogged(func):defwrapper(*args,**kwargs):print('Calling',func.__name__)returnfunc(*args,**kwargs)returnwrapper使用这个函数:defadd(x,y):returnx+ylogged_add=logged(add)调用logged返回的函数会发生什么?logged_add(3,4)#你会看到日志消息出现这个例子说明了创建所谓的包装函数的过程。包装器是一个函数,它通过额外的处理来包装另一个函数,但在其他方面与原始函数完全一样。>>>logged_add(3,4)Callingadd#额外输出。由包装器添加>>>注意:logged()函数创建一个包装器并将其作为结果返回。装饰器在Python中,在函数内部使用包装器是很常见的。因为它很常见,所以有一种特殊的语法。defadd(x,y):returnx+yadd=logged(add)#特殊语法@loggeddefadd(x,y):returnx+y这个特殊语法执行与上面完全相同的步骤。装饰器只是一种装饰函数的新语法。请注意,装饰器有许多比此处显示的更微妙的细节,例如在类中使用装饰器,或为同一功能使用多个装饰器。但是,这里的示例很好地展示了如何使用它们。通常,它是对出现在各种函数定义中的重复代码的响应。装饰器可以将重复的代码移至中央定义。Exercise练习7.10:时序装饰器如果你定义了一个函数,函数的名称和它所属的模块的名称分别存储在__name__和__module__属性中。示例:>>>defadd(x,y):returnx+y>>>add.__name__'add'>>>add.__module__'__main__'>>>请创建timethis.py文件并在文件中写入timethis(功能)功能。timethis(func)函数用额外的逻辑层包装一个函数,打印出函数执行所需的事件。为此,您将向该函数添加以下定时调用。start=time.time()r=func(*args,**kwargs)end=time.time()print('%s.%s:%f'%(func.__module__,func.__name__,end-start))(timethis(func))装饰器工作原理示例:>>>fromtimethisimporttimethis>>>@timethisdefcountdown(n):whilen>0:n-=1>>>countdown(10000000)__main__.countdown:0.076562>>>讨论:@timethis装饰器可以放在任何函数的前面,也就是说,你应该把装饰器作为性能调优的诊断工具。目录|上一节(7.3返回函数)|下一节(7.5装饰方法)注:完整翻译见https://github.com/codists/practical-python-zh

猜你喜欢