9.11 装饰器为被包装函数增加参数

上传人:豆浆 文档编号:36334079 上传时间:2018-03-27 格式:PDF 页数:4 大小:88.95KB
返回 下载 相关 举报
9.11 装饰器为被包装函数增加参数_第1页
第1页 / 共4页
9.11 装饰器为被包装函数增加参数_第2页
第2页 / 共4页
9.11 装饰器为被包装函数增加参数_第3页
第3页 / 共4页
9.11 装饰器为被包装函数增加参数_第4页
第4页 / 共4页
亲,该文档总共4页,全部预览完了,如果喜欢就下载吧!
资源描述

《9.11 装饰器为被包装函数增加参数》由会员分享,可在线阅读,更多相关《9.11 装饰器为被包装函数增加参数(4页珍藏版)》请在金锄头文库上搜索。

1、9.11 装饰器为被包装函数增加参数问题你想在装饰器中给被包装函数增加额外的参数,但是不能影响这个函数现有的调规 则。解决案可以使关键字参数来给被包装函数增加额外参数。考虑下的装饰器:from functools import wrapsdef optional_debug(func):wraps(func)def wrapper(*args, debug=False, *kwargs):if debug:print(Calling, func._name_)return func(*args, *kwargs)return wrapper optional_debug . def spam(

2、a,b,c): . print(a,b,c) . spam(1,2,3) 1 2 3 spam(1,2,3, debug=True) Calling spam 1 2 3 讨论通过装饰器来给被包装函数增加参数的做法并不常见。尽管如此,有时候它可以避免 些重复代码。例如,如果你有下这样的代码:def a(x, debug=False):if debug:print(Calling a)def b(x, y, z, debug=False):if debug:print(Calling b)def c(x, y, debug=False):if debug:print(Calling c)那么你可

3、以将其重构成这样:from functools import wraps import inspectdef optional_debug(func):if debug in inspect.getargspec(func).args:raise TypeError(debug argument already defined)wraps(func)def wrapper(*args, debug=False, *kwargs):if debug:print(Calling, func._name_)return func(*args, *kwargs)return wrapperoption

4、al_debug def a(x):passoptional_debug def b(x, y, z):passoptional_debug def c(x, y):pass这种实现案之所以得通,在于强制关键字参数很容易被添加到接受 *args 和 *kwargs 参数的函数中。通过使强制关键字参数,它被作为个特殊情况被挑选 出来,并且接下来仅仅使剩余的位置和关键字参数去调这个函数时,这个特殊参 数会被排除在外。也就是说,它并不会被纳到 *kwargs 中去。还有个难点就是如何去处理被添加的参数与被包装函数参数直接的名字冲突。例 如,如果装饰器 optional_debug 作在个已经拥有个

5、debug 参数的函数上时会有问题。这我们增加了步名字检查。上的案还可以更完美点,因为精明的程序员应该发现了被包装函数的函数签名 其实是错误的。例如: optional_debug . def add(x,y): . return x+y . import inspect print(inspect.signature(add) (x, y) 通过如下的修改,可以解决这个问题:from functools import wraps import inspectdef optional_debug(func):if debug in inspect.getargspec(func).args:r

6、aise TypeError(debug argument already defined)wraps(func)def wrapper(*args, debug=False, *kwargs):if debug:print(Calling, func._name_)return func(*args, *kwargs)sig = inspect.signature(func)parms = list(sig.parameters.values()parms.append(inspect.Parameter(debug,inspect.Parameter.KEYWORD_ONLY,default=False)wrapper._signature_ = sig.replace(parameters=parms)return wrapper通过这样的修改,包装后的函数签名就能正确的显 debug 参数的存在了。例如: optional_debug . def add(x,y): . return x+y . print(inspect.signature(add) (x, y, *, debug=False) add(2,3) 5 参考9.16节获取更多关于函数签名的信息。W3Cschool()最的技术知识分享与学习平台此篇内容来于站户上传并发布。

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 行业资料 > 其它行业文档

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号