笔记-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. (一)Hybrid app混合开发模式

    hybrid app是什么? 这里我们先看一下词条上的定义 Hybrid App:Hybrid App is a mobile application that is coded in both br ...

  2. sharepoint2007就地升级2010系列(五)升级到sharepoint2010

    ---恢复内容结束--- 大家下午好 今天我们来完成最后一步,sharepoint2007升级2010.其实我反倒没有那么紧张了,因为我最担心的数据库升级,已经过了. OK,话不多说,让我们直接开始吧 ...

  3. 刚刚写的一个lua下解释csv的工具。

    csvtool = {} function csvtool:csv2table(filename) if type(filename) ~= "string" or filenam ...

  4. 炫酷的Html+css (一)

    博客园在别的 博主看到一个样式, 里面有一段这样的 正方体旋转的 动态图 吸引了我. 找博主要了代码, 贴出来 与大家共享. 鼠标放上去会展开 一大一小两个正方体, 鼠标悬浮上去, 外面的正方体会展开 ...

  5. linux基础命令-chgrp/chown/chomd

    chgrp 改变所属用户组 要被改变的组名必须要在/etc/group文件内存在才行: chgrp [-R]   dirname/filename -R:进行递归的持续更改,连同子目录下的所有文件.目 ...

  6. MAC读取希捷移动硬盘ntfs

    希捷提供了mac读取ntfs磁盘的软件,Paragon. 搜索关键词 "希捷" "mac" 或者通过以下链接进入 https://www.seagate.com ...

  7. reactjs--父组件调用子组件的内部方法(转载)

    reactjs--父组件调用子组件的内部方法 发表于2016/10/11 9:21:37  965人阅读 1.引入相关js <script src="js/react.js" ...

  8. 详解 CSS 居中布局技巧

    水平居中元素: 通用方法,元素的宽高未知 方式一:CSS3 transform .parent { position: relative; } .child { position: absolute; ...

  9. css3中的 @Keyframes

    一.介绍 keyframes被称为关键帧,其类似于Flash中的关键帧.在CSS3中其主要以“@keyframes”开头,后面跟着是动画名称加上一对花括号“{…}”,括号中是一些不同时间段样式规则. ...

  10. C语言中%p,%u,%lu都有什么用处

    %p表示输出这个指针, %d表示后面的输出类型为有符号的10进制整形, %u表示无符号10进制整型, %lu表示输出无符号长整型整数 (long unsigned)