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
    

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

  • 相关阅读:
    HDU4411 最小费用流
    HDU5934 强连通分量
    一个问题
    SAP模板
    KMP模板
    ]C#中执行SQL文件脚本的代码(非常有用)
    C#调用非托管程序5种方式
    [转]C#中的静态常量(const)和动态常量(static和readonly)用法和区别
    [转]C#开发命名规范总结整理
    [转]关于同步方法里面调用异步方法的探究
  • 原文地址:https://www.cnblogs.com/zhqin/p/9949794.html
Copyright © 2011-2022 走看看