Python自定义注解
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自定义注解的更多相关文章
- 自定义注解-方法重试@RetryProcess
背景 在项目开发中,有时候会出现接口调用失败,本身调用又是异步的,如果是因为一些网络问题请求超时,总想可以重试几次把任务处理掉. 一些RPC框架,比如dubbo都是有重试机制的,但是并不是每一个项目多 ...
- java自定义注解类
一.前言 今天阅读帆哥代码的时候,看到了之前没有见过的新东西, 比如java自定义注解类,如何获取注解,如何反射内部类,this$0是什么意思? 于是乎,学习并整理了一下. 二.代码示例 import ...
- Jackson 通过自定义注解来控制json key的格式
Jackson 通过自定义注解来控制json key的格式 最近我这边有一个需求就是需要把Bean中的某一些特殊字段的值进行替换.而这个替换过程是需要依赖一个第三方的dubbo服务的.为了使得这个转换 ...
- 自定义注解之运行时注解(RetentionPolicy.RUNTIME)
对注解概念不了解的可以先看这个:Java注解基础概念总结 前面有提到注解按生命周期来划分可分为3类: 1.RetentionPolicy.SOURCE:注解只保留在源文件,当Java文件编译成clas ...
- JAVA自定义注解
在学习使用Spring和MyBatis框架的时候,使用了很多的注解来标注Bean或者数据访问层参数,那么JAVA的注解到底是个东西,作用是什么,又怎样自定义注解呢?这篇文章,即将作出简单易懂的解释. ...
- 用大白话聊聊JavaSE -- 自定义注解入门
注解在JavaSE中算是比较高级的一种用法了,为什么要学习注解,我想大概有以下几个原因: 1. 可以更深层次地学习Java,理解Java的思想. 2. 有了注解的基础,能够方便阅读各种框架的源码,比如 ...
- [javaSE] 注解-自定义注解
注解的分类: 源码注解 编译时注解 JDK的@Override 运行时注解 Spring的@Autowired 自定义注解的语法要求 ① 使用@interface关键字定义注解 ② 成员以无参无异常方 ...
- 使用spring aspect控制自定义注解
自定义注解:这里是一个处理异常的注解,当调用方法发生异常时,返回异常信息 /** * ErrorCode: * * @author yangzhenlong * @since 2016/7/21 */ ...
- ssm+redis 如何更简洁的利用自定义注解+AOP实现redis缓存
基于 ssm + maven + redis 使用自定义注解 利用aop基于AspectJ方式 实现redis缓存 如何能更简洁的利用aop实现redis缓存,话不多说,上demo 需求: 数据查询时 ...
随机推荐
- css文本省略号
这里记录下如何用CSS实现单行.多行文本溢出容器的时候用省略号代替溢出部分. 单行文本溢出容器时显示省略号的CSS实现方法 /* 规定当内容溢出元素框(容器)时隐藏 */ overflow: hidd ...
- laravel中select2多选,初始化默认选中项
项目中有发送消息功能,需要能通过搜索,多选用户,来指定发送人.使用 select2 插件来完成. select2 的 html 代码如下: <div class="form-group ...
- [算法]LeetCode 152:乘积最大子序列
题目描述: 给定一个整数数组 nums ,找出一个序列中乘积最大的连续子序列(该序列至少包含一个数). 示例 1: 输入: [2,3,-2,4]输出: 6解释: 子数组 [2,3] 有最大乘积 6.示 ...
- Linux 网络相关命令 Cheat Sheet
以下漫画形式呈现的常用 Linux 网络相关命令速查表来自 twitter -
- DevExpress的分页Tab控件XtraTabControl控件的使用
场景 Winform控件-DevExpress18下载安装注册以及在VS中使用: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/1 ...
- RESTFul&HTTP GET简介
RestApi:https://www.cnblogs.com/springyangwc/archive/2012/01/18/2325784.html RESTFul API设计指南:http:// ...
- iOS安全攻防(一):Hack必备的命令与工具
转自:http://blog.csdn.net/yiyaaixuexi/article/details/8288077 你的应用正在被其他对手反向工程.跟踪和操作!你的应用是否依旧裸奔豪不防御? 郑重 ...
- SQLi-LABS Page-3 (Stacked injections) Less-38-Less-45
Less-38 堆叠注入原理简介堆叠注入简介 Stacked injections: 堆叠注入.从名词的含义就可以看到应该是一堆 sql 语句(多条)一起执行.而在真实的运用中也是这样的, 我们知道在 ...
- MES系统在小批量电子行业生产管理中的应用
小批量电子产品生产管理的主要问题 电子电器制造类企业,既有单件小批量生产,也有批量生产:有按库存生产,也有按订单生产,属于典型的离散制造行业.因产品的不同其生产工艺流程也不尽相同,生产设备的布置不是按 ...
- 删除带外键的表【foreign key constraint fails】报错
title: 删除带外键的表[foreign key constraint fails]报错 date: 2018-08-02 21:59:06 tags: 数据库 --- 遥想当时正在学hibern ...