博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
python3 如何给装饰器传递参数
阅读量:6070 次
发布时间:2019-06-20

本文共 2905 字,大约阅读时间需要 9 分钟。

引子

  之前写过一篇文章用来讲解装饰器() 、那篇文章的定位是入门级的

  所以也就没有讲过多的高级主题,决定在这里讲一下如果为装饰器传递参数

 

目标

  我们有两个函数“add_fun”、“add” 其中“add_fun”已经过时、如果用户有调用这个函数的话就提示它“add_fun”已经过时并且引导

  它去调用“add”函数

 

add\add_fun函数的定义

def add_fun(x,y):    """    实现两个数相加、并返回合    """    return x+ydef add(x,y):    """    实现两个数相加、并返回合    """    return x+y

 

通过装饰器引导调用add_fun的用户去调用add

def deprecated(fun,new_fun_name):    """deprecated函数会返回一个叫inner的函数、inner函数会返回    fun调用的结果,与直接调用fun得到值不同的是inner会先打印一行提示    表明fun已经过时    """    def inner(x,y):        print("{fun.__name__} 函数已经过时 请使用{new_fun_name}".format(fun=fun,new_fun_name=new_fun_name))        return fun(x,y)    return innerdef add_fun(x,y):    """    实现两个数相加、并返回合    """    return x+yadd_fun = deprecated(add_fun,'add')def add(x,y):    """    实现两个数相加、并返回合    """    return x+y    if __name__=="__main__":    print(add_fun(1,1))

  调用时的输出如下:

python3 dc.pyadd_fun 函数已经过时 请使用add2

 

难道为装饰器增加参数就这么的简单

  仔细的你可能已经发现了、我们在上面的代码里并没有用装饰器的语法糖衣、而是通过函数调用的方式来包装的add_fun方法

add_fun = deprecated(add_fun,'add')

  机智的你应该想到了@deprecated('add') 这样去装饰add_fun应该也能成吧!于是代码如下(关键代码)

@deprecated('add')def add_fun(x,y):    """    实现两个数相加、并返回合    """    return x+y

  当你调用时会发现完全不是你想要的那样、

python3 dc.pyTraceback (most recent call last):  File "dc.py", line 12, in 
@deprecated('add')TypeError: deprecated() missing 1 required positional argument: 'new_fun_name'

  事实上目前语法糖衣只解决了最简单的情况、如果你要给@写法 指定参数还要另寻它法。

 

真理简洁而有力

  linux的世界里有句话“一切皆文件”,python的世界里也有一句话“一切皆对象”; 但是关键不是会“背”,而是“领悟”。

  一个经典的糖衣格式是这样的

@decoratedef fun():    pass

  请仔细看一下不难发现@后面直接是对象名、由python的数据模式可知、对象名只是一个对象的标识;也就是说@后面是一个对象!对象可以

  是已经定义好的,也可以是调用才生成。明白这一层道理之后事情就比较好办了,我们只要在调用时生成“装饰”对象就可以了,因为要调用

  所以就给了我们传递参数的机会。

 

触摸真理一

   用调用时生成的对象用作装饰器

def deprecated(new_fun_name):    """derepcated 装饰器把函数标记为过时    """    def warpper(fun):        """        """        def inner(*args):            print("{0} 函数已经过时 请使用 {1}".format(fun.__name__,new_fun_name))            return fun(*args)        return inner        return warpperdecorator = deprecated('add') # 特意把这一步单独分离出来、用于说明什么叫调用时创建的对象用作做装饰器@decorator                    # 特意把这一步单独分离出来、用于说明什么叫调用时创建的对象用作做装饰器def add_fun(x,y):    """    实现两个数相加、并返回合    """    return x+ydef add(x,y):    """    实现两个数相加、并返回合    """    return x+y    if __name__=="__main__":   print(add_fun(1,1))

 

  

触摸真理二

  与语法糖衣结合、完成传递参数的目的

def deprecated(new_fun_name):    """derepcated 装饰器把函数标记为过时    """    def warpper(fun):        """        """        def inner(*args):            print("{0} 函数已经过时 请使用 {1}".format(fun.__name__,new_fun_name))            return fun(*args)        return inner        return warpper@deprecated('add')def add_fun(x,y):    """    实现两个数相加、并返回合    """    return x+ydef add(x,y):    """    实现两个数相加、并返回合    """    return x+y    if __name__=="__main__":   print(add_fun(1,1))

  调用时输出如下

python3 dc.pyadd_fun 函数已经过时 请使用 add2

 

 

总结:

  如果只能用一名话概括python我想对简洁的应该是“一切皆对象”了吧。

 

转载于:https://www.cnblogs.com/JiangLe/p/9309566.html

你可能感兴趣的文章
Windows Azure 保留已存在的虚拟网络外网IP(云服务)
查看>>
修改字符集
查看>>
HackTheGame 攻略 - 第四关
查看>>
js删除数组元素
查看>>
带空格文件名的处理(find xargs grep ..etc)
查看>>
华为Access、Hybrid和Trunk的区别和设置
查看>>
centos使用docker下安装mysql并配置、nginx
查看>>
关于HTML5的理解
查看>>
需要学的东西
查看>>
Internet Message Access Protocol --- IMAP协议
查看>>
Linux 获取文件夹下的所有文件
查看>>
对 Sea.js 进行配置(一) seajs.config
查看>>
dom4j解析xml文件
查看>>
第六周
查看>>
斯坦福大学公开课机器学习:梯度下降运算的学习率a(gradient descent in practice 2:learning rate alpha)...
查看>>
解释一下 P/NP/NP-Complete/NP-Hard 等问题
查看>>
javafx for android or ios ?
查看>>
微软职位内部推荐-Senior Software Engineer II-Sharepoint
查看>>
sql 字符串操作
查看>>
【转】Android布局优化之ViewStub
查看>>