zoukankan      html  css  js  c++  java
  • python_3 装饰器参数之谜

    装饰器参数之谜

    之前已经初步了解过装饰器了,知道了装饰器可以“偷梁换柱”,在不改变函数的调用方式和函数内容的时候,而把函数的功能偷偷地修改。
    那么问题来了,如果被修改的函数中有参数的话,怎么样去写这个装饰函数呢?Ok,废话不多说,先上程序:

    def func(bar):
    
        def dec():
            bar()
            print("this is dec")
        return dec
    
    @func   #test1 = func(test1)
    def test1(name):
        print("this is test1 and I'm",name)
    
    test1()
    

    很显然,程序会报错:
    in dec bar()
    TypeError: test1() missing 1 required positional argument: 'name'

    报错说test1()缺少位置参数'name',ok,我们来看程序,首先@func中,func(bar)中执行的是: bar = test1,func()中的内容并没有执行,然后就将dec作为返回值返回,此时,相当于执行了:test1 = dec,然后给test1加了个(),也就是调用text1(),那么其实就是相当于调用的是dec,也就是dec(),那么把参数放到dec中就OK了,也就是dec(name),当然,下面跟着执行的bar()其实是执行test1(),给他括号中也添加上name就可以了。问题解决。如下:

    def func(bar):
    
        def dec(name):
            bar(name)
            print("this is dec")
        return dec
    
    @func   #test1 = func(test1)
    def test1(name):
        print("this is test1 and I'm",name)
    
    test1("Jack")
    

    输出:

    this is test1 and I'm Jack
    this is dec
    

    OK,问题2,如果被装饰的函数有好多个呢?其中有的函数不需要参数,有的函数需要3个,有的函数需要9个,这样的话,同一个装饰器装饰不同的函数肯定是会报错的,因为不同的函数的参数是不同的。那么如何解决呢?这里有一个非固定参数的表示办法,有参数你就传进来,没参数就不用你传,也不会报错。是不是很棒?程序如下:

    def func(bar):
    
        def dec(*args,**kwargs):
            bar(*args,**kwargs)
            print("this is dec")
        return dec
    
    @func   #test1 = func(test1)
    def test1(name):
        print("this is test1 and I'm",name)
    
    @func
    def test2():
        print("this is test2")
    test1("Jack")
    test2()
    

    输出为:

    this is test1 and I'm Jack
    this is dec
    this is test2
    this is dec
    

    是不是很方便,并且不管你需要装饰的函数有多少参数都无所谓,这个统统包容。

  • 相关阅读:
    Zebra命令模式分析(一)  分析
    sublime text2
    开源路由软件zebra的命令存储原理及使用方法
    开源路由软件zebra介绍和和在Linux环境下的安装
    jQuery删除节点
    如何成为一名软件架构师
    jQuery中的DOM操作
    编写自己的Shell解释器
    Notepad++集成VC2010环境
    ffmpeg使用语法
  • 原文地址:https://www.cnblogs.com/zhqin/p/9949794.html
Copyright © 2011-2022 走看看