Python的装饰器用法学习笔记
作者:cangmean 发布时间:2021-05-06 03:03:36
标签:Python,装饰器
在python中常看到在定义函数是使用@func. 这就是装饰器, 装饰器是把一个函数作为参数的函数,常常用于扩展已有函数,即不改变当前函数状态下增加功能.
def run():
print "I'm run."
我有这么一个函数, 我想知道这个函数什么时候开始什么时候结束. 我应该这么写
def run():
print time.ctime()
print "I'm run."
print time.ctime()
但是如果不允许修改函数的话就需要装饰器了
def count(func):
def wrapper():
print time.ctime()
ret = func()
print time.ctime()
return ret
return wrapper
@count
def run():
print "I'm run."
# print '2015-4-10'
eg:
def now():
print '2015-4-10'
f = now
f()
函数有一个__name__ 对象 可通过 dir(func) func为定义的函数名
now.__name__ # print 'now'
f.__name__ # print 'now'
print f # print '<function now at 0x000000000213A908>'
print now # print '<function now at 0x000000000213A908>'
我们通过装饰器打印log日志
def log(func):
def wrapper(*args, **kwargs):
print "call %s()" % func.__name__
return func(*args, **kwargs)
return wrapper
@log
def now():
print '2015-4-10'
now() # print 'call now()'
其实装饰器修饰函数相当于, now = log(now) 也就是装饰器函数把被修饰的函数当参数后赋给同名的变量
functools.wraps 函数
当我们使用了装饰器后now的__name__值发生了改变
# 没有使用前
now.__name__ # print 'now'
# 使用后
now.__name__ # print 'wrapper'
当我们使用装饰器前,now.__name__使用的是当前now函数,但使用后 now这个函数其实是 log(now) 也就是log函数的返回值也就是被包裹的wrapper. 解决方法是functools.wraps函数.
装饰闭包, 使用前得调用 import functools
def log(func):
@functools.wraps(func)
def wrapper(*args, **kwargs):
...
带参数的装饰器
如果decorator需要传入参数, 那就需要在写一个返回decorator的高阶函数. 写出来更复杂.
def login(level):
def _deco(func):
def wrapper(*args, **kwargs):
if level >= 5:
print '用户 VIP 等级 %d' % int(level-5)
else:
print '用户 * 丝 等级 %d' % abs(level-5)
return func(*args, **kwargs)
return wrapper
return _deco
@login(5)
def user(username):
print 'welcome, %s' % username
# 用户vip 等级0
# welcome, mink
user('mink')
带参数的decorator等于func = 装饰器函数(装饰器参数)(func)
装饰器类
通过类的__call__可以想使用函数一样使用类
class A(object):
def __init__(self, func):
self.func = func
def __call__(self):
return self.func() ** 2
@A
def foo():
return 10
print foo() # print 100


猜你喜欢
- 相关概念并发:指一个时间段内,有几个程序在同一个cpu上运行,但是任意时刻只有一个程序在cpu上运行。比如说在一秒内cpu切换了100个进程
- 1.对于一维数组,可以有:2. 对于二维数组:考虑可将其看作为矩阵,故可以如下书写二重遍历 这里外层循环的是二维数组A的行,内层则
- int(整型)在32位机器上,整数的位数为32位,取值范围为-2**31~2**31-1,即-2147483648~2147483647在6
- Flask是一个用Python编写的Web应用程序框架,Flask是python的web框架,最大的特征是轻便,让开发者自由灵活的兼容要开发
- 本教程为大家分享了win10下Python环境安装配置教程,供大家参考,具体内容如下1.在https://www.python.org/do
- 方法说明: 同步版的 stat() 。方法返回一个stat数组对象,包含以下信息:(以下信息为案例中读取的文件信息,非默认值){
- python networkx来生成一个图使用python提供的第三方的库networkx,networkx是专门用来生成图论和网络科学里面
- 好难受,上次发了做游戏的居然没人看,每天为了给你们写啥,老夫心都操碎了~真的是,今天来给大家爬一波短视频网站吧,都是些很养眼的~网站地址在代
- 引子首先说 正则表达式是什么?正则表达式,又称正规表示式、正规表示法、正规表达式、规则表达式、常规表示法(英语:Regular Expres
- 在pyhton中,经常会用到input()语句,但是input()语句输入的内容只能时字符串类型,而我们经常要输入int类型的数据等,那么就
- 这里使用的是mysql Ver 14.14 Distrib 5.6.19, for Linux (i686) using EditLine
- 在Python中如何实现单例模式?这可以说是一个经典的Python面试题了。这回我们讲讲实现Python中实现单例模式的n种方式,和它的原理
- Python脚本有一个毛病,当使用相对路径时,被另一个不同目录下的py文件中导入时,会报找不到对应文件的问题。感觉是当前工作目录变成了导入p
- Angular中根据适用场景定义了很多生命周期函数,其本质上是事件的响应函数,其中最常用的就是ngOnInit。但在TypeScript或E
- 1、之前那个说淘宝交易评价“有问题”的文章已经有了一百多个评论。(某些开口就骂的评论已被删除)近期去评论的人都是从搜索引擎过来的,他们不是产
- 在使用数据库的时候,难免要在使用过程中进行删除的操作,如果是使用int类型的字段,令其自增长,这是个最简单的办法,但是后果会有些不是你想要的
- 10线程同时操作,频繁出现插入同样数据的问题。虽然在插入数据的时候使用了: insert inti tablename(fields....
- 本文实例讲述了Python实现生成随机数据插入mysql数据库的方法。分享给大家供大家参考,具体如下:运行结果:实现代码:import ra
- aspjpeg组件实现加水印函数的调用方法: <%printwater "/images/水印图片.gif",&q
- 目标在本章中,将学习"Harris Corner Detection”背后的思想函数:cv2.cornerHa