• 一个关于python装饰器参数的问题


    看到廖雪峰python教程上,python装饰器一章

    https://www.liaoxuefeng.com/wiki/0014316089557264a6b348958f449949df42a6d3a2e542c000/0014318435599930270c0381a3b44db991cd6d858064ac0000

    在最后的作业题上

    再思考一下能否写出一个@log的decorator,使它既支持:

    @log
    def f():
        pass

    又支持:

    @log('execute')
    def f():
        pass

    即在装饰器头上加str,从而牵扯出了一个装饰器参数传入的问题。

    讨论区有人留言

    用户6223899516_84125 created at 6天前, Last updated at 6天前
    import functools
    import time
    
    def log2(text=None):
        def decorator(func):
            @functools.wraps(func)
            def wrapper(*args,**kw):
                if isinstance(text,(int,str)):
                    print('%s begin call %s():' %(text,func.__name__))
                    func(*args,**kw)
                    print('%s end call %s():' %(text,func.__name__))
                else:
                    print('begin call %s():' % func.__name__)
                    func(*args,**kw)
                    print('end call %s():' % func.__name__)
                return
            return wrapper
        return decorator if isinstance(text,(int,str)) else decorator(text) 
    
    @log2
    def now2():
        print('now is:'+time.asctime())
    
    now2()
    
    @log2('timeshow')
    def now3():
        print('now is:'+'2017-07-10')
    
    now3()

    最后的if语句其实我是参考其他人的,但是我突然觉得很不理解, 为什么if有参数的时候是 return decorator, 而else(无参数)的时候是 return decorator(text)

    谁能给解释一下。。我怎么总觉得写反了呢?不过从结果来看是对的~

    以及下面的回复

    在调试里面跑了一下,不写参数的时候,text拿到的实际是函数对象,就是本来func应该拿到的那个,结果让text提前吃掉了,截胡了你程序里的now。

    这里不写字符串的话,text不会拿到None,而是直接被赋值成函数。调试里面跑到这一步,text的属性是指向一个function。

    如果把return里面那个decorator(text) 直接改成decorator,执行会提示缺参数。因为内层的func这个量已经没参数可接了。

    decorator(text) 的意思就是,如果发现text不是str类型,那么就是本该传给内层func的函数让外层提前拿走了,并且放在了text里面。这时应该手动把text传给里面那层,于是就return了 decorator(text)


    通过这个问题,大概搞明白装饰器参数传入的问题了。
    python应该会从外层向内层逐层匹配。
  • 相关阅读:
    关于 <customErrors> 标记的“mode”属性设置为“Off”的问题的解决方案
    ASP.NET MVC的帮助类HtmlHelper和UrlHelper
    js判断手机浏览器操作系统和微信浏览器的方法
    javascript倒计时代码及倒计时弹窗
    修改UISearchBar背景色
    dispatch_group_async
    Block 代替for循环
    GCD 延时操作
    GCD 倒计时
    创建UIButton
  • 原文地址:https://www.cnblogs.com/gk2017/p/7196736.html
Copyright © 2020-2023  润新知