引子

  之前写过一篇文章用来讲解装饰器(https://www.cnblogs.com/JiangLe/p/9309330.html) 、那篇文章的定位是入门级的

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

目标

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

  它去调用“add”函数

add\add_fun函数的定义

def add_fun(x,y):
"""
实现两个数相加、并返回合
"""
return x+y def 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 inner def add_fun(x,y):
"""
实现两个数相加、并返回合
"""
return x+y add_fun = deprecated(add_fun,'add') def add(x,y):
"""
实现两个数相加、并返回合
"""
return x+y if __name__=="__main__":
print(add_fun(1,1))

  调用时的输出如下:

python3 dc.py
add_fun 函数已经过时 请使用add

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

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

add_fun = deprecated(add_fun,'add')

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

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

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

python3 dc.py
Traceback (most recent call last):
File "dc.py", line , in <module>
@deprecated('add')
TypeError: deprecated() missing required positional argument: 'new_fun_name'

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

真理简洁而有力

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

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

@decorate
def 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 warpper decorator = deprecated('add') # 特意把这一步单独分离出来、用于说明什么叫调用时创建的对象用作做装饰器 @decorator # 特意把这一步单独分离出来、用于说明什么叫调用时创建的对象用作做装饰器
def add_fun(x,y):
"""
实现两个数相加、并返回合
"""
return x+y def 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+y def add(x,y):
"""
实现两个数相加、并返回合
"""
return x+y if __name__=="__main__":
print(add_fun(1,1))

  调用时输出如下

python3 dc.py
add_fun 函数已经过时 请使用 add

总结:

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

python3 如何给装饰器传递参数的更多相关文章

  1. python 装饰器 传递参数简单案例

    def debug(func): def wrapper(*args, **kwargs): # 指定宇宙无敌参数 print "[DEBUG]: enter {}()".form ...

  2. 装饰器,装饰器多参数的使用(*arg, **kwargs),装饰器的调用顺序

    一.#1.执行outer函数,并且将其下面的函数名,当作参数 #2.将outer的返回值重新赋值给f1 = outer的返回值 #3.新f1 = inner #4.func = 原f1 #!/usr/ ...

  3. typescript装饰器 方法装饰器 方法参数装饰器 装饰器的执行顺序

    /* 装饰器:装饰器是一种特殊类型的声明,它能够被附加到类声明,方法,属性或参数上,可以修改类的行为. 通俗的讲装饰器就是一个方法,可以注入到类.方法.属性参数上来扩展类.属性.方法.参数的功能. 常 ...

  4. python_如何修改装饰器中参数?

    案例: 为分析程序内哪些函数执行时间开销较大,我们需定义一个带timeout参数的装饰器 需求: 统计被装饰函数的运行时间 时间大于timeout时,将此次函数调用记录到log日志中 运行时可以修改t ...

  5. Python学习第四十一天函数装饰器传参数的用法

    在不改变函数的结构的基础,我们给函数加新的功能,用是函数装饰器,如果要给函数传递参数,那么应该怎么做呢 @timerdef test2(name,age): time.sleep(3) print(' ...

  6. 笔记||Python3进阶之装饰器

    # 装饰器# 特征: 是用一个@开头的字符串# 装饰器通常用来装饰函数.或者类的方法# 被装饰后的函数,通常是在原有的函数基础上,会多出增加一点功能# 一般来说装饰器本身也是一个函数## def te ...

  7. python3 进一步了解装饰器 NLP第四条

    还是先来抄一段NLP第四条: 四,只有感官经验塑造出来的世界,没有绝对的真实世界   每个人运用自己的感觉器官把资料摄入(摄入过程),由于感官运用是主观地有选择性的,因此不能,亦不需要把所有资料捕获. ...

  8. 【python3】 函数 装饰器

    第一步 : 了解装饰器 装饰器模式,重点在于装饰,装饰的核心仍是被装饰的对象. 举一个栗子:我今天穿了一件短袖,但是突然一阵风,短袖没办法为我御寒,我想到的办法是将短袖变得更厚更长,但是改造之后,它就 ...

  9. Python3基础笔记--装饰器

    装饰器是十二分重要的高级函数. 参考博客:装饰器 所需前提知识: 1.作用域: LEGB 2.高阶函数 高阶函数是至少满足下列一个条件的函数: 1)接受一个或多个函数作为输入 2)输出一个函数 注意理 ...

随机推荐

  1. Python 模块浅析

    如果你退出Python解释器重新进入,以前创建的一切定义(变量和函数)就全部丢失了.因此,如果你想写一些长久保存的程序,最好使用一个文本编辑器来编写程序,把保存好的文件输入解释器. 我们称之为创建一个 ...

  2. Echart 仪表盘和柱形图

    我们来分布讲解: 1.首先编一写一个html,如下: <html> <body class=""> <div class="containe ...

  3. WINDOWS7 下 xclient 802.1x 客户端 停止运行的解决办法

    昨天下午,由于FOXMAIL 出现问题,修改了一个地方,导致xclient 停止运行.具体解决办法如下:右击“计算机”-进入“系统属性”-->“高级”-->"设置"-- ...

  4. sqlserver 表中记录生成insert,可以加条件,可以生成建表语句

    sqlserver 表中记录生成insert,可以加条件,可以生成建表语句 create PROCEDURE [sp_getinsert] ( ) , --如果非默认架构,可以加上架构名 例如:sch ...

  5. Oracle Data Integrator 12c-第一个映射

    一.创建"项目" 设计器->项目,点击插入项目图标, 在项目对话框的"定义"标签下输入项目名称如ODI_Exercise ,保存 二.导入知识模块 项目→ ...

  6. Oracle Data Integrator学习资料

    http://docs.oracle.com/middleware/1213/odi/index.html https://docs.oracle.com/middleware/1213/core/O ...

  7. django之创建第8个项目-数据库配置及同步研究

    1.sqlitestudio-2.1.5数据库可视化工具--百度云盘下载 2.编写C:\djangoweb\helloworld\blog\models.py文件 # Create your mode ...

  8. 转 php 5.3.6中php-fpm 配置

    php 5.3.6 中 php-fpm 配置 成 服务启动 从php5.3.3开始 源码中开始包含 php-fpm,不用专门再打补丁了,只需要解开源码直接configure, 关于php-fpm的编译 ...

  9. UltraEdit编辑器|UE

    目前对我而言,还是比较喜欢editplus/notepad++. 注册码: UltraEdit-32 v15.00注册码:free userGGCDP-KIOGN-KQHLZ-RNCSK-KKKHZ- ...

  10. 基于RESTful API 怎么设计用户权限控制?

    前言 有人说,每个人都是平等的:也有人说,人生来就是不平等的:在人类社会中,并没有绝对的公平,一件事,并不是所有人都能去做:一样物,并不是所有人都能够拥有.每个人都有自己的角色,每种角色都有对某种资源 ...