笔记-python-functool-@wraps

1.      wraps

经常看到@wraps装饰器,查阅文档学习一下

在了解它之前,先了解一下partial和updata_wrapper这两个前置技能,因为在wraps中用到了。

1.1.    partial

偏函数

源代码:

class partial:

"""New function with partial application of the given arguments

and keywords.

"""

__slots__ = "func", "args", "keywords", "__dict__", "__weakref__"

def __new__(*args, **keywords):

if not args:

raise TypeError("descriptor '__new__' of partial needs an argument")

if len(args) < 2:

raise TypeError("type 'partial' takes at least one argument")

cls, func, *args = args

if not callable(func):

raise TypeError("the first argument must be callable")

args = tuple(args)

if hasattr(func, "func"):

args = func.args + args

tmpkw = func.keywords.copy()

tmpkw.update(keywords)

keywords = tmpkw

del tmpkw

func = func.func

self = super(partial, cls).__new__(cls)

self.func = func

self.args = args

self.keywords = keywords

return self

def __call__(*args, **keywords):

if not args:

raise TypeError("descriptor '__call__' of partial needs an argument")

self, *args = args

newkeywords = self.keywords.copy()

newkeywords.update(keywords)

return self.func(*self.args, *args, **newkeywords)

重点关注构造方法和调用方法,可以看出整体的作用等效于构造一个新了函数,但新的函数包括了原函数的参数,多用于简化代码。

实现原理/过程:实际上返回的是一个partial实例(可调用),有三个重要属性,self.func指向传入函数,args和keywords为可变参数;
调用返回的partial对象实质上是执行func()

案例如下:

def u(a,b,*args):

pass

u1 = partial(u,4,5,7)

print('u: {1}{0}u1: {2}{0}u1.func: {3}{0}u1.args: {4}'.format('\n',u,u1,u1.func,u1.args))

输出:

u: <function u at 0x000000130F5FB378>
u1: functools.partial(<function u at 0x000000130F5FB378>, 4, 5, 7)
u1.func: <function u at 0x000000130F5FB378>
u1.args: (4, 5, 7)

>>>

1.2.    update_wrapper

def update_wrapper(wrapper,

wrapped,

assigned = WRAPPER_ASSIGNMENTS,

updated = WRAPPER_UPDATES):

"""Update a wrapper function to look like the wrapped function

wrapper is the function to be updated

wrapped is the original function

assigned is a tuple naming the attributes assigned directly

from the wrapped function to the wrapper function (defaults to

functools.WRAPPER_ASSIGNMENTS)

updated is a tuple naming the attributes of the wrapper that

are updated with the corresponding attribute from the wrapped

function (defaults to functools.WRAPPER_UPDATES)

"""

for attr in assigned:

try:

value = getattr(wrapped, attr)

except AttributeError:

pass

else:

setattr(wrapper, attr, value)

for attr in updated:

getattr(wrapper, attr).update(getattr(wrapped, attr, {}))

# Issue #17482: set __wrapped__ last so we don't inadvertently copy it

# from the wrapped function when updating __dict__

wrapper.__wrapped__ = wrapped

# Return the wrapper so this can be used as a decorator via partial()

return wrapper

简单来说,就是把wrapper的相关属性改成和wrapped相同的。返回wrapper

1.3.    wraps

回到wraps

def wraps(wrapped,

assigned = WRAPPER_ASSIGNMENTS,

updated = WRAPPER_UPDATES):

"""Decorator factory to apply update_wrapper() to a wrapper function

Returns a decorator that invokes update_wrapper() with the decorated

function as the wrapper argument and the arguments to wraps() as the

remaining arguments. Default arguments are as for update_wrapper().

This is a convenience function to simplify applying partial() to

update_wrapper().

"""

return partial(update_wrapper, wrapped=wrapped,

assigned=assigned, updated=updated)

核心就一句,实际就是一个修饰器版的update_wrapper,将被修饰的函数(wrapped)

注意这里的写法,wrapped=wrapped,对偏函数而言,该参数写成关键字参数与写成位置参数-wrapped-所带来的结果不一样。

注意,下面这种写法会导致结果反转:

return partial(update_wrapper, wrapped,

assigned=assigned, updated=updated)

1.4.    总结

wraps装饰器的作用就是更改函数名称和属性。

当使用装饰器装饰一个函数时,函数本身就已经是一个新的函数;即函数名称或属性产生了变化。所以在装饰器的编写中建议加入wraps确保被装饰的函数不会因装饰器带来异常情况。

笔记-python-functool-@wraps的更多相关文章

  1. python functools.wraps functools.partial实例解析

    一:python functools.wraps 实例 1. 未使用wraps的实例 #!/usr/bin/env python # coding:utf-8 def logged(func): de ...

  2. functool.wraps and functools.partial

    functools.partial 通过包装手法,允许我们 "重新定义" 函数签名.  通常是将函数的部分参数给固定下来, 从而形成一个输入参数更少的新函数. functool.w ...

  3. 笔记-python操作mysql

    笔记-python操作mysql 1.      开始 1.1.    环境准备-mysql create database db_python; use db_python; create tabl ...

  4. 笔记-python异常信息输出

    笔记-python异常信息输出 1.      异常信息输出 python异常捕获使用try-except-else-finally语句: 在except 语句中可以使用except as e,然后通 ...

  5. 笔记-python -asynio

    笔记-python -asynio 1.      简介 asyncio是做什么的? asyncio is a library to write concurrent code using the a ...

  6. 笔记-python lib-pymongo

    笔记-python lib-pymongo 1.      开始 pymongo是python版的连接库,最新版为3.7.2. 文档地址:https://pypi.org/project/pymong ...

  7. 笔记-python tutorial-9.classes

    笔记-python tutorial-9.classes 1.      Classes 1.1.    scopes and namespaces namespace: A namespace is ...

  8. MongoDB学习笔记:Python 操作MongoDB

    MongoDB学习笔记:Python 操作MongoDB   Pymongo 安装 安装pymongopip install pymongoPyMongo是驱动程序,使python程序能够使用Mong ...

  9. 机器学习实战笔记(Python实现)-08-线性回归

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

  10. 机器学习实战笔记(Python实现)-05-支持向量机(SVM)

    --------------------------------------------------------------------------------------- 本系列文章为<机器 ...

随机推荐

  1. es6-正则

    RegExp构造函数 在ES5中,RegExp构造函数的参数有两种情况. 第一种情况是,参数是字符串,这时第二个参数表示正则表达式的修饰符(flag). var regex = new RegExp( ...

  2. CSS命名规范(规则)

    常用的CSS命名规则 头:header内容:content/container尾:footer导航:nav侧栏:sidebar栏目:column页面外围控制整体佈局宽度:wrapper左右中:left ...

  3. SSL Labs: Increased Penalty When TLS 1.2 Is Not Supported

    https://community.qualys.com/blogs/securitylabs/2015/05/22/ssl-labs-increased-penalty-when-tls-12-is ...

  4. CEFSharp在anycpu下的编译

    记录一篇博文,将CEFSharp在AnyCpu下使用: 地址:http://pengxiaobo123.blog.163.com/blog/static/20471515420172164593726 ...

  5. session的MaxInactiveInterval=0在tomcat6和tomcat8不同表现

    在tomcat6中调用 request.getSession().setMaxInactiveInterval(0); 这个session会立即过期. 而在tomcat8中,同样的调用,会导致这个se ...

  6. May 2 2017 Week 18 Tuesday

    The beauty of the journey is found in the scenery along the way. 旅行之美在于沿途所见的风景. Several years ago, I ...

  7. Laravel5 构造器高级查询条件写法

    <?php #DB 高级查询 // select * from table where A and B or C $all_data = DB::table("shopnc_goods ...

  8. c# 语法 字符串内插

    结果截屏 参考文章 https://www.cnblogs.com/csproj/p/Interpolated_Strings.html c# 6.0语法 https://www.cnblogs.co ...

  9. P2082 区间覆盖(加强版)

    题目 #include<iostream> #include<algorithm> #include<cstring> using namespace std; s ...

  10. Search in Rotated Sorted Array——LeetCode

    Suppose an array sorted in ascending order is rotated at some pivot unknown to you beforehand. (i.e. ...