python装饰器(新年第一写)
祭奠碌碌无为的2018,想想其实也不算碌碌无为,至少我还搞懂了装饰器,写了一堆有用没用的玩意
原来觉得装饰器挺难的,直到2018年的最后几天,突然就明白了,难道这就是传说中的开天聪么
言归正传,之所以觉得装饰器难,是因为这东西不按套路出牌,希望大家看完我写的也能在新的一年里有所收货吧
先说下要实现的功能,写一个装饰器,让装饰器可以把时间加到日志的行首,例如
20190101 000001 write log first values
20190101 000001使用装饰器写入,而write log first values使用函数写入
首先写一个正常的写入日志的函数
def write_log(values):
return values
函数介绍:一段简单的函数,只是将values写入并返回,看起来像脱了裤子放屁,先这样,后面调用装饰器的时候是需要用这个函数的
测试下函数
write_values = 'write log first values'
result = write_log(write_values)
print result
正常写入,查看文件内容
write log first values
因为需要写入时间,所以还需要一个写入处理时间的函数
import time
def now_time():
local_time = time.localtime(time.time())
time_format = '%Y%m%d %H%M%S'
time_result = time.strftime(time_format,local_time)
return time_result
函数介绍:将当前日期转换成需要的日期格式
测试下函数
now = now_time()
print now
结果是
20190101 013041
日期正常,再来写个装饰器函数
敲小黑板,这里是重点,重点,重点,重要的事情说三遍---------------------------------------------------------
def add_time_line_start(func1):
def insert_time():
now = now_time()
return now +' ' + func1()
return insert_time
函数介绍:首先定义了一个装饰器函数add_time_line_start,传入了一个参数是func1,之所以说装饰器不按套路出牌这里是诡异地方1,这里传入的func1参数其实是个函数,并不是我们平常认为的一个字符串或者list什么的,接下来是装饰器里面的insert_time函数,这个函数是装饰器的功能函数,也就是装饰器需要实现的功能在这里实现。说一下insert_time的功能,获取到当前时间,并且把当前时间拼到传入的函数前面返回。最后最外层是返回inser_time函数,即将拼接好的结果返回
测试下函数,这里需要全部的函数了,现在把全部函数都放进来,存成一个文件叫zsq.py
#!/usr/bin/python
# coding: UTF-8 import time # 日期时间函数
def now_time():
local_time = time.localtime(time.time())
time_format = '%Y%m%d %H%M%S'
time_result = time.strftime(time_format,local_time)
return time_result # 装饰器函数
def add_time_line_start():
def insert_time():
now = now_time()
return now + ' ' + func1()
return insert_time #调用装饰器
@add_time_line_start #看起来没什么用的函数
def write_log(values):
return values write_values = 'write log first values'
result = write_log(write_values)
print result
这里看到了调用装饰器是使用的@方法,@add_time_line_start,说下我的理解,这个其实就是等于平常函数的add_time_line_start(write_log())这种方法,这也就是装饰器不按套路出牌这里是诡异地方2
测试下
python zsq.py
结果是
Traceback (most recent call last):
File "zshq1.py", line 28, in <module>
print write_log(write_values)
TypeError: insert_time() takes no arguments (1 given)
卧槽,报错了,为什么,这也是个坑,为这个真是研究了半天,因为传入装饰器的函数有传参,所以insert_time()需要同步传参,但是传什么呢,这里有个特殊用法,在函数传参的地方写上self就好了,下面是改正后的结果def insert_time(): return now + ' ' + func1()注意这两个地方
#!/usr/bin/python
# coding: UTF-8 import time # 日期时间函数
def now_time():
local_time = time.localtime(time.time())
time_format = '%Y%m%d %H%M%S'
time_result = time.strftime(time_format,local_time)
return time_result # 装饰器函数
def add_time_line_start(func1):
def insert_time(self):
now = now_time()
return now + ' ' + func1(self)
return insert_time #调用装饰器
@add_time_line_start #看起来没什么用的函数
def write_log(values):
return values def write_log1(values):
return values write_values = 'write log first values'
result = write_log1(write_values)
print result
再测试下
python zsq.py
结果是
20190101 022028 write log first values
这次OK了,安心睡觉咯,留个疑问吧,就是这个装饰器是不是对下面所有的函数都会复用呢,答案当然是自己动手试试咯
python装饰器(新年第一写)的更多相关文章
- 你必须学写 Python 装饰器的五个理由
你必须学写Python装饰器的五个理由 ----装饰器能对你所写的代码产生极大的正面作用 作者:Aaron Maxwell,2016年5月5日 Python装饰器是很容易使用的.任何一个会写Pytho ...
- Python装饰器详解
python中的装饰器是一个用得非常多的东西,我们可以把一些特定的方法.通用的方法写成一个个装饰器,这就为调用这些方法提供一个非常大的便利,如此提高我们代码的可读性以及简洁性,以及可扩展性. 在学习p ...
- Python装饰器由浅入深
装饰器的功能在很多语言中都有,名字也不尽相同,其实它体现的是一种设计模式,强调的是开放封闭原则,更多的用于后期功能升级而不是编写新的代码.装饰器不光能装饰函数,也能装饰其他的对象,比如类,但通常,我们 ...
- Python装饰器与面向切面编程
今天来讨论一下装饰器.装饰器是一个很著名的设计模式,经常被用于有切面需求的场景,较为经典的有插入日志.性能测试.事务处理等.装饰器是解决这类问题的绝佳设计,有了装饰器,我们就可以抽离出大量函数中与函数 ...
- python 装饰器、递归原理、模块导入方式
1.装饰器原理 def f1(arg): print '验证' arg() def func(): print ' #.将被调用函数封装到另外一个函数 func = f1(func) #.对原函数重新 ...
- Python高级特性: 12步轻松搞定Python装饰器
12步轻松搞定Python装饰器 通过 Python 装饰器实现DRY(不重复代码)原则: http://python.jobbole.com/84151/ 基本上一开始很难搞定python的装 ...
- Python 装饰器入门(下)
继续上次的进度:https://www.cnblogs.com/flashBoxer/p/9847521.html 正文: 装饰类 在类中有两种不通的方式使用装饰器,第一个和我们之前做过的函数非常相似 ...
- Python 装饰器入门(上)
翻译前想说的话: 这是一篇介绍python装饰器的文章,对比之前看到的类似介绍装饰器的文章,个人认为无人可出其右,文章由浅到深,由函数介绍到装饰器的高级应用,每个介绍必有例子说明.文章太长,看完原文后 ...
- (转)python装饰器二
Python装饰器进阶之二 保存被装饰方法的元数据 什么是方法的元数据 举个栗子 def hello(): print('Hello, World.') print(dir(hello)) 结果如下: ...
随机推荐
- android开发(3):列表listview的实现 | 下拉刷新
APP里面的列表太常用了,系统提供的listview或grideview可以做到.另外,我希望这个列表能够下拉时触发刷新,于是考虑使用封装了这个功能的开源项目,这里介绍这个: https://gith ...
- Tomcat8源码笔记(四)Server和Service初始化
上一章 简单说明下Tomcat各个组件: Server:服务器,Tomcat服务器,一个Tomcat只有一个Server组件; Service:业务层,是Server下最大的子容器,一个Server可 ...
- IS-IS笔记
IS-IS:一般不会见到,唯一见到过一次是在BAT中某家的骨干网 |->CLNP (类似IP,IPX)|->CLNS->|->IS-IS (Routing,IGP)ISO-&g ...
- loadrunner:Action.c(4): Error -27796: Failed to connect to server "192.168.66.3:8080": [10060] Connection timed out
Action.c(4): Error -27796: Failed to connect to server "192.168.66.3:8080": [10060] Connec ...
- Apollo 2 如何支持 @Value 注解自动更新
前言 Apollo 在 v0.10.0 版本后,支持自动更新.v0.10.0之前的版本在配置变化后不会重新注入,需要重启才会更新. 也就是说,如果一个属性加入了 @Value 注解,并且这个配置在配置 ...
- EF SaveChanges() 报错(转载)
最佳答案 报这个错是因为,提交了主键重复的数据,虽然未提交到数据库中 但是现在的EF上下文中已经包含了我提交的数据,下次在提交正确数据时, 原来添加到上下文中的数据依然还在..如何处理这个问题呢? ...
- (转)分享一个技巧,利用批处理调用ruby脚本(可能你为路径苦恼)
#关闭命令显示 @echo off #提示信息 echo Now,listing the controller,please not shutdown the DOS File! #切换到当前路径,. ...
- 修改git分支名称
场景:将分支名称为 oldbranch 改为 newbranch 步骤: 1.将本地分支oldbranch切一个分支到本地 git branch -m oldbranch newbranch 2.删除 ...
- linux部分常见指令
游走指令 cd: 进入指定位置 cd / 进入到根目录 cd /home 进入到home文件夹 cd - 进入上次所在文件夹 比如 在 / 时 cd /usr/local到loca ...
- HDU4278
Faulty Odometer Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others)T ...