Python装饰器(2)name和doc

内容纯属个人理解,不对之处,欢迎指点。

装饰问题:__name__和__doc__

接着上回分解,在我们给函数添加了计算运行时间的功能后(准确来说应该是执行某函数时我们同时对函数做了一些操作,毕竟一个函数的存在就是为了完成某一个具体的功能,而不是多个),其实装饰器也对函数做了一些其他的修改。
示例:

def deco(func):
    '''i am deco'''
    def wrap(*args, **kwargs):
        '''i am wrap'''
        return func(*args, **kwargs)
    return wrap


@deco
def foo():
    '''i am foo'''
    print("---foo---")

当我们执行foo():

>> foo()
---foo---

此时似乎还没有问题,但是当我们查看函数文档和函数名字时:

>> foo.__doc__
'i am wrap'
>> foo.__name__
'wrap'

此时问题就来了,函数的信息被修改了,然而这并不是我们想要的结果,究其原因,还是装饰器装饰过程中的问题。
我们来看一下装饰器的装饰过程:

1. wrap = deco(foo)  # 将foo函数传入deco函数,并返回内部的wrap函数
2. foo = wrap  # 将wrap函数赋给foo
3. foo()  # 执行foo函数

由上可以看到,此时的foo已经不是原来的foo了,确切的说,它已经变成了wrap,是wrap赋值给了foo,所以才有了执行foo时可以执行添加的功能,也就是执行了wrap。所以当我们查看foo函数的docstring和name时,显示的是wrap函数的docstring和name。

问题总有解决的办法。

from functools import wraps


def deco(func):
    '''i am deco'''

    @wraps(func)
    def wrap(*args, **kwargs):
        '''i am wrap'''
        return func(*args, **kwargs)
    return wrap


@deco
def foo():
    '''i am foo'''

    print("---foo---")

此时再运行:

>> foo()
---foo---
>> foo.__name__
foo
>> foo.__doc__
i am foo

functools中的wraps可以保留原函数的__name__和__doc__,不使其发生改变,这样才是更好的装饰。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 包(lib)、模块(module) 在Python中,存在包和模块两个常见概念。 模块:编写Python代码的py...
    清清子衿木子水心阅读 9,214评论 0 27
  • 每个人都有的内裤主要功能是用来遮羞,但是到了冬天它没法为我们防风御寒,咋办?我们想到的一个办法就是把内裤改造一下,...
    chen_000阅读 5,157评论 0 3
  • Spring Cloud为开发人员提供了快速构建分布式系统中一些常见模式的工具(例如配置管理,服务发现,断路器,智...
    卡卡罗2017阅读 135,973评论 19 139
  • 《老子上的优雅课》 不要你齐家治国平天下 只要你从中学会好好享受生活 做一个取悦自己的温柔小女子 前言: 《道德经...
    再顾阅读 3,126评论 0 0
  • 写了一大堆后来实在搞不懂这个格式怎么调..利用谓词查找本地数据的demo
    马铃薯蜀黍阅读 1,706评论 9 0

友情链接更多精彩内容