Python3.0之后加入新特性Decorators,以@为标记修饰function和class。有点类似c++的宏和java的注解。Decorators用以修饰约束function和class,分为带参数和不带参数,影响原有输出,例如类静态函数我们要表达的时候需要函数前面加上修饰@staticmethod或@classmethod,为什么这样做呢?下面用简单的例子来看一下,具体内容可以查看:官方解释

不带参数的单一使用

def spamrun(fn):
def sayspam(*args):
print("spam,spam,spam")
fn(*args)
return sayspam
@spamrun
def useful(a,b):
print(a*b) if __name__ == "__main__"
useful(2,5)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11

运行结果

spam,spam,spam
10
  • 1
  • 2

函数useful本身应该只是打印10,可是为什么最后的结果是这样的呢,其实我们可以简单的把这个代码理解为

def spamrun(fn):
def sayspam(*args):
print("spam,spam,spam")
fn(*args)
return sayspam def useful(a,b):
print(a*b) if __name__ == "__main__"
useful = spamrun(useful)
useful(a,b)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12

不带参数的多次使用

def spamrun(fn):
def sayspam(*args):
print("spam,spam,spam")
fn(*args)
return sayspam def spamrun1(fn):
def sayspam1(*args):
print("spam1,spam1,spam1")
fn(*args)
return sayspam1 @spamrun
@spamrun1
def useful(a,b):
print(a*b) if __name__ == "__main__"
useful(2,5)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20

运行结果

spam,spam,spam
spam1,spam1,spam1
10
  • 1
  • 2
  • 3

这个代码理解为

if __name__ == "__main__"
useful = spamrun1(spamrun(useful))
useful(a,b)
  • 1
  • 2
  • 3

带参数的单次使用

def attrs(**kwds):
def decorate(f):
for k in kwds:
setattr(f, k, kwds[k])
return f return decorate @attrs(versionadded="2.2",
author="Guido van Rossum")
def mymethod(f):
print(getattr(mymethod,'versionadded',0))
print(getattr(mymethod,'author',0))
print(f) if __name__ == "__main__"
mymethod(2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

运行结果

2.2
Guido van Rossum
2
  • 1
  • 2
  • 3

这个代码理解为

if __name__ == "__main__"
mymethod = attrs(versionadded="2.2",
author="Guido van Rossum).(mymethod)
mymethod(2)
  • 1
  • 2
  • 3
  • 4

带参数的多次使用 
这次我们来看一个比较实际的例子,检查我们函数的输入输出是否符合我们的标准,比如我们希望的输入是(int,(int,float))输出是(int,float),这个例子在官网里有,但是在3.6版本中使用有些问题,这里进行了一些改动,如果要进一步了解可以看下functionTool。

def accepts(*types):
def check_accepts(f):
def new_f(*args, **kwds):
assert len(types) == (len(args) + len(kwds)), \
"args cnt %d does not match %d" % (len(args) + len(kwds), len(types))
for (a, t) in zip(args, types):
assert isinstance(a, t), \
"arg %r does not match %s" % (a, t)
return f(*args, **kwds) update_wrapper(new_f, f)
return new_f return check_accepts def returns(rtype):
def check_returns(f):
def new_f(*args, **kwds):
result = f(*args, **kwds)
assert isinstance(result, rtype), \
"return value %r does not match %s" % (result, rtype)
return result update_wrapper(new_f, f)
return new_f return check_returns @accepts(int, (int, float))
@returns((int, float))
def func(arg1, arg2):
return arg1 * arg2 if __name__ == "__main__"
a = func(1, 'b')
print(a)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38

这里故意输入了错误的参数,所以运行结果将我们的断言打印了出来

AssertionError: arg 'b' does not match (<class 'int'>, <class 'float'>)
  • 1

这个代码理解为

if __name__ == "__main__"
func = accepts(int, (int, float)).(accepts((int, float)).(mymethod))
a = func(1, 'b')
print(a)
  • 1
  • 2
  • 3
  • 4

说到这里,大家不难看出其实我们可以使用Decorators做很多工作,简化代码,使逻辑更清晰等。还有更多的用法等着大家自己去挖掘了,这里只简单的介绍了针对函数的用法,其实还可以针对class使用,具体的大家自己看看官方介绍,结合这篇文档应该就不难理解了。

引自:https://blog.csdn.net/u013474436/article/details/75675113

Python自定义注解的更多相关文章

  1. 自定义注解-方法重试@RetryProcess

    背景 在项目开发中,有时候会出现接口调用失败,本身调用又是异步的,如果是因为一些网络问题请求超时,总想可以重试几次把任务处理掉. 一些RPC框架,比如dubbo都是有重试机制的,但是并不是每一个项目多 ...

  2. java自定义注解类

    一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...

  3. Jackson 通过自定义注解来控制json key的格式

    Jackson 通过自定义注解来控制json key的格式 最近我这边有一个需求就是需要把Bean中的某一些特殊字段的值进行替换.而这个替换过程是需要依赖一个第三方的dubbo服务的.为了使得这个转换 ...

  4. 自定义注解之运行时注解(RetentionPolicy.RUNTIME)

    对注解概念不了解的可以先看这个:Java注解基础概念总结 前面有提到注解按生命周期来划分可分为3类: 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成clas ...

  5. JAVA自定义注解

    在学习使用Spring和MyBatis框架的时候,使用了很多的注解来标注Bean或者数据访问层参数,那么JAVA的注解到底是个东西,作用是什么,又怎样自定义注解呢?这篇文章,即将作出简单易懂的解释. ...

  6. 用大白话聊聊JavaSE -- 自定义注解入门

    注解在JavaSE中算是比较高级的一种用法了,为什么要学习注解,我想大概有以下几个原因: 1. 可以更深层次地学习Java,理解Java的思想. 2. 有了注解的基础,能够方便阅读各种框架的源码,比如 ...

  7. [javaSE] 注解-自定义注解

    注解的分类: 源码注解 编译时注解 JDK的@Override 运行时注解 Spring的@Autowired 自定义注解的语法要求 ① 使用@interface关键字定义注解 ② 成员以无参无异常方 ...

  8. 使用spring aspect控制自定义注解

    自定义注解:这里是一个处理异常的注解,当调用方法发生异常时,返回异常信息 /** * ErrorCode: * * @author yangzhenlong * @since 2016/7/21 */ ...

  9. ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存

    基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...

随机推荐

  1. java在hashmap初始化时赋初值

    Java中的HashMap是一种常用的数据结构,一般用来做数据字典或者Hash查找的容器. 一般我们初始化并赋初值是这样做的: HashMap<String, Object> map = ...

  2. wp.editor.initialize 配置案例

    wp.editor.initialize ( 'EditorTextArea' , { tinymce: { wpautop: to true , theme: 'modern' , skin: 'l ...

  3. python爬取昵称并保存为csv

    代码: import sys import io import re sys.stdout=io.TextIOWrapper(sys.stdout.buffer,encoding='gb18030') ...

  4. Python 情人节超强技能 导出微信聊天记录生成词云

    前言 本文的文字及图片来源于网络,仅供学习.交流使用,不具有任何商业用途,版权归原作者所有,如有问题请及时联系我们以作处理. 作者: Python实用宝典 PS:如有需要Python学习资料的小伙伴可 ...

  5. 关于yield和yield from

    一.简单示例 def yield_func(): for _ in range(2): yield "12" def yield_from_func(): for _ in ran ...

  6. Python【day 14-3】二分法查找

    #二分法查找 #方法1 循环+左右边界变动,两者差减半 #方法2 递归+新列表长度减半 #方法3 递归+左右边界变动,两者差减半 #方法1 循环+左右边界变动,两者差减半 def recursion1 ...

  7. django3-路由系统进阶

    1.django的url到底是什么 就是路径 ,看成django的目录 ,每个目录对应个视图函数 ,当然一个url仅能对应一个函数 2.url的格式 url(正则表达式,views函数名,参数,别名) ...

  8. 作用域,作用域链,垃圾收集,js解析

    变量中包含基本数据类型和引用数据类型,基本类型指简单的数据值,引用类型由多个值构成的对象. 引用类型可以为其添加属性和方法,也可以改变和删除属性和方法. 复制变量值:     基本类型:一个变量向另一 ...

  9. Dynamics CRM 客户端程序开发:在实体的列表界面添加按钮

    关注本人微信和易信公众号: 微软动态CRM专家罗勇 ,回复114或者20140312可方便获取本文,同时可以在第一时间得到我发布的最新的博文信息,follow me! 如果没有安装Ribbon Wor ...

  10. Android apk签名方法介绍

    还望支持个人博客站:http://www.enjoytoday.cn 参考博客:http://www.enjoytoday.cn/posts/203 为什么要签名 在介绍签名方法之前,首先我们来了解下 ...