【python基础学习】基础重点难点知识汇总
2024-09-02 05:29:43
python中decorator装饰器
语法示例:
@decorator
什么是装饰器:
问题:
定义一个函数后
在运行时动态增加功能
又不想改动函数本身的代码
示例:
# 希望对下列函数调用增加log功能,打印出函数调用:
def f1(x):
return x*
def f2(x):
return x*x
def f3(x):
return x*x*x
方法1:直接修改原函数的定义
def f1(x):
print('call f1')
return x*
def f2(x):
print('call f2')
return x*x
def f3(x):
print('call f3')
return x*x*x
有没有更简单的方法?
高阶函数
. 可以接受函数作为参数
. 可以返回函数
是否可以接受一个函数,对其进行包装,然后返回一个新函数?
方法2:通过高阶函数返回新函数(装饰器函数):
def f1(x):
return x*
def new_fn(f):
def fn(x):
print('call'+f.__name__+'()')
return f(x)
return fn
调用1:
g1 = new_fn(f1)
print( g1() )
调用2:
f1 = new_fn(f1)
print( f1() )
装饰器:
python内置@语法就是为了简化装饰器调用
@new_fn
def f1(x):
return x*
等同于:
def f1(x):
return x*
f1 = new_fn(f1)
装饰器的作用:
可以极大简化代码,避免每个函数编写重复性的代码
打印日志:@log
检测性能:@performance
数据库事务:@transaction
URL路由:@post('/register')
装饰器示例:
1. 如果自定义函数存在两个形参,上述装饰器函数内部固定写了一个形参,会出现错误怎么办:
@new_fn
def add(x,y):
return x+y
# 这里会出现错误,所以需要更改 new_fn 函数如下:
def new_fn(f):
def fn(*args, **kwargs):
print('call'+f.__name__+'()')
return f(*args, **kwargs)
return fn
2. 请编写一个@performance,它可以打印出函数调用的时间。计算函数调用的时间可以记录调用前后的当前时间戳,然后计算两个时间戳的差。
import time
def performance(f):
def fn(*args, **kw):
t1 = time.time()
r = f(*args, **kw)
t2 = time.time()
print 'call %s() in %fs' % (f.__name__, (t2 - t1))
return r
return fn @performance
def factorial(n):
return reduce(lambda x,y: x*y, range(, n+))
print factorial()
3.上述装饰器函数只能接受一个函数参数,如果装饰器函数需要传入额外的参数怎么办?
@log('DEBUG')
def my_func():
pass
把上面的定义翻译成高阶函数的调用,就是:
my_func = log('DEBUG')(my_func)
上面的语句看上去还是比较绕,再展开一下:
log_decorator = log('DEBUG')
my_func = log_decorator(my_func)
上面的语句又相当于:
log_decorator = log('DEBUG')
@log_decorator
def my_func():
pass
所以,带参数的log函数首先返回一个decorator函数,再让这个decorator函数接收my_func并返回新函数:
def log(prefix):
def log_decorator(f):
def wrapper(*args, **kw):
print '[%s] %s()...' % (prefix, f.__name__)
return f(*args, **kw)
return wrapper
return log_decorator @log('DEBUG')
def test():
pass
print test()
上述第二个例子:@performance只能打印秒,请给 @performace 增加一个参数,允许传入's'或'ms':
import time
import functools
def performance(unit):
def perf_decorator(f):
@functools.wraps(f)
def wapper(*args, **kw):
t1 = time.time()
r = f(*args, **kw)
t2 = time.time()
t = (t2 - t1) * if unit=='ms' else (t2 - t1)
print 'call %s() in %f %s' % (f.__name__, t,unit)
return r
return wapper
return perf_decorator @performance('ms')
def factorial(n):
return reduce(lambda x,y: x*y, range(, n+))
print factorial()
print factorial.__name__
完善的装饰器写法:
最新文章
- SourceInsight阅读Python---张子芳
- Winform 窗体控件随窗体自动(等比例)调整大小
- JQ中的延迟对象deferred中的promise等的使用
- 读javascript高级程序设计16-几条函数小技巧
- 关于DateTime和String转换的容易犯得错误
- float浮动引起的ul高度崩溃与overflow的关系
- 如何给Qlabel添加clicked属性(覆盖mousePressEvent,处理QMouseEvent消息,反正是软绘制,想怎么样就怎么样)
- 深拷贝与浅拷贝(mutableCopy与Copy)详解 iOS
- sublime3 使用技巧
- Cocos2d-X中间应用
- CSS中文字体的英文名称 – 前台开发必备
- svn服务端安装、权限修改以及客户端的使用
- 常用UI框架
- html学习之路--简单图片轮播
- postgresql 自定义聚合函数
- C语言 · 单词数统计
- 2015-10-20 sql2
- DB通用类:SQL Server 通用类库
- [Apio2008]免费道路[Kruscal]
- Django之前端插件定制之表头
热门文章
- JavaScript 之 history对象
- Redhat6.5安装oracle11g
- url请求时,参数中的+在服务器接收时为空格,导致AES加密报出javax.crypto.IllegalBlockSizeException: Input length must be multiple of 16 when decrypting with padded cipher
- Centos7永久修改IP地址(NAT模式)
- Detectron2源码阅读笔记-(二)Registry&;build_*方法
- 第二篇 -- C#中对XML操作
- Mysql 行锁 for update
- Spring Boot 之:Spring Boot Admin
- HDU - 6643: Ridiculous Netizens(点分治+依赖背包+空间优化)
- SpringBoot——报错总结