python functools.wraps

我们在使用装饰器的时候,有些函数的功能会丢失,比如func.__name__,func.__doc__,func.__module__
比如下面这个例子:
In [16]: def logged(func):
    ...:     def with_logging(*args,**kwargs):
    ...:         print(func.__name__+" was called ")
    ...:         return func(*args,**kwargs)
    ...:     return with_logging
    ...: 

In [17]: @logged
    ...: def f(x):
    ...:     """ does some math """
    ...:     return x+x*x
    ...: 

In [18]: f(2)
f was called
Out[18]: 6

In [19]: print(f.__name__)  # 本来应该输出的是f,但是装饰器装饰之后就失去了func.__name__的功能
with_logging

In [20]: print(f.__doc__)  # 同上
None

那么怎么才能实现这些在装饰器装饰下失去的功能呢?
可以使用 functools 模块下的wraps,functools.wraps 则可以将原函数对象的指定属性复制给包装函数对象, 默认有 __module__、__name__、__doc__,或者通过参数选择
In [ 9 ]: from functools import wraps
In [10]: def logged(func):
    ...:     @wraps(func)
    ...:     def with_logging(*args,**kwargs):
    ...:         print(func.__name__+" was called ")
    ...:         return func(*args,**kwargs)
    ...:     return with_logging
    ...: 

In [11]: @logged
    ...: def f(x):
    ...:     """ does some math """
    ...:     return x+x*x
    ...: 

In [12]: print(f.__name__)
f

In [13]: print(f.__doc__)
 does some math 

In [14]: f(2)
f was called
Out[14]: 6

原文地址:https://www.cnblogs.com/nyist-xsk/p/9343393.html

时间: 2024-10-17 02:23:53

python functools.wraps的相关文章

python functools.wraps装饰器模块

# -*-coding=utf-8 -*- __author__ = 'piay' import time, functools def foo(): ''' 定义一个普通函数 :return: ''' print 'this is foo' foo() ''' 这里如果我们需要查看函数执行时间,修改为: ''' def foo1(): start_time = time.clock() print 'this is foo1' end_time = time.clock() print '执行

Python 中实现装饰器时使用 @functools.wraps 的理由

Python 中使用装饰器对在运行期对函数进行一些外部功能的扩展.但是在使用过程中,由于装饰器的加入导致解释器认为函数本身发生了改变,在某些情况下--比如测试时--会导致一些问题.Python 通过 functool.wraps 为我们解决了这个问题:在编写装饰器时,在实现前加入 @functools.wraps(func) 可以保证装饰器不会对被装饰函数造成影响.比如,在 Flask 中,我们要自己重写 login_required 装饰器,但不想影响被装饰器装饰的方法,则 login_req

Python的wraps修饰器详解

本文和大家分享的主要是python 中wraps 修饰器相关内容,一起来看看吧,希望对大家 学习python有所帮助. 在了解  wraps  修饰器之前,我们首先要了解  partial  和  update_wrapper  这两个函数,因为在 wraps  的代码中,用到了这两个函数. partial 首先说  partial  函数,在  官方文档  的描述中,这个函数的声明如下:  functools.partial(func, *args, **keywords)  .它的作用就是返

python functools模块

functools.partial 作用: functools.partial 通过包装手法,允许我们 "重新定义" 函数签名 用一些默认参数包装一个可调用对象,返回结果是可调用对象,并且可以像原始对象一样对待 冻结部分函数位置函数或关键字参数,简化函数,更少更灵活的函数参数调用 #args/keywords 调用partial时参数 def partial(func, *args, **keywords): def newfunc(*fargs, **fkeywords): newk

Python——functools

该模块为高阶函数提供支持——作用于或返回函数的函数被称为高阶函数.在该模块看来,一切可调用的对象均可视为本模块中所说的“函数”. 目录 一.模块方法 1. functools.cmp_to_key(func) 2. functools.total_ordering(cls) 3. functools.reduce(function, iterable[, initializer]) *4. functools.partial(func[,*args][, **keywords]) 5. func

@functools.wraps(func)

- 先记住一句话:自定义python装饰器时一定要记住使用@functools.wraps(func)修饰wrapper - 在Flask中使用装饰器遇到AssertionError: View function mapping is overwriting an existing... - 报错的大概意思就是存在相同的view,在flask中,如果定义了两个相同函数名的view,就会报这种报这种错误,例如: - 但是上例中的两个函数名分别是index和course,是不相同的,为什么会报这种错

functools.wraps

我们在使用 Decorator 的过程中,难免会损失一些原本的功能信息.直接拿 stackoverflow 里面的栗子 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 def logged(func): def with_logging(*args, **kwargs): print func.__name__ + " was called" return func(*args, **kwargs) return with_logging @l

Python functools.partial

def declare_consumer(self, consumer_cls, topic, callback): """Create a Consumer using the class that was passed in and add it to our list of consumers """ def _connect_error(exc): log_info = {'topic': topic, 'err_str': str(ex

functools.wraps定义函数装饰器

def tracer(func): def wrapper(*args, **kwargs): result = func(*args, **kwargs) print('%s(%r,%r)->%r'%(func.__name__,args,kwargs,result)) return result return wrapper @tracer def fibonacci(n): if n in (0,1): return n return (fibonacci(n-1)+fibonacci(n