Python168的学习笔记8
#coding:utf8 #斐波那契数列,第三项起,每一项都等于前两项之和 def memo(func):
cache = {}#闭包
def wrap(*args):
if args not in cache:
cache[args] = func(*args)
return cache[args]
return wrap @memo
def fibonacci(n):
if n<=1:
return 1
return fibonacci(n-1)+fibonacci(n-2) #上楼梯算法,总过n个台阶,一次只能迈a-b个台阶,不能后退,问有几种走法
@memo
def climb(n,steps):
count = 0
if n==0:
count = 1
elif n>0:
for step in steps:
count += climb(n-step,steps)
return count
装饰器的简单应用还是明白的,但是要理解这两个递归算法。
关于函数的元数据,如:f.__name__,指的是def时指定的名字;f.__doc__,指的是函数文档字符串;f.__moudle__,指的是函数所属模块;f.__default__,指的是函数默认值;f.__dict__,指的是属性字典;f.__closure__,指的是函数的闭包。。。这些元数据都是func的属性。
使用装饰器可能会改变func的元数据。
#coding:utf8
from functools import update_wrapper,wraps,WRAPPER_ASSIGNMENTS,WRAPPER_UPDATES def mydecorator(func):
@wraps(func)#第一种
def wrapper(*args,**kw):
'''wrapper function'''
print 'In wrapper'
func(*args,**kw)
#wrapper.__name__ = func.__name__ 第二种
#update_wrapper(wrapper,func,('__name__','__doc__'),('__dict__',))#第四个参数是将func的属性更新到wrap
#第三种:update_wrapper后两个的默认参数分别是('__module__', '__name__', '__doc__');('__dict__',)
return wrapper @mydecorator
def example():
'''example function'''
print 'In example'
其实就是对处理后的func的属性进行重新赋回原来的值。
定义带参数的装饰器,就是用去判断参数的类型,因为要用过python3的库,所以先略过。
修改装饰器的属性。这样的好处是能够在运行中动态修改,而不是每次都要去装饰器处修改。
给包裹函数增加一个函数,作为包裹函数的属性,使其可以修改闭包中的自由变量。
import time
from functools import wraps
import logging def warn(timeout):
timeout = [timeout]#将参数设为只有一个数的list
def decorator(func):
@wraps(func)
def wrapper(*args,**kw):
start = time.time()
res = func(*args,**kw)
used = time.time()-start
if used > timeout[0]:
msg = '%s : %s >%s' %(func.__name__,used,timeout[0])
logging.warn(msg)
return res
def setTimeout(k):#注意这里
timeout[0] = k
wrapper.setTimeout = setTimeout
return wrapper
return decorator from random import randint
@warn(0.5)
def test():
print 'In test'
while randint(0,1):
print 'I am sleep'
time.sleep(1) for _ in range(10):
test() test.setTimeout(1)
for _ in range(10):
test()
使用类来定制装饰器。
#coding:utf8
import logging
from time import localtime,time,strftime,sleep class CallingInfo(object):
def __init__(self,name):
log = logging.getLogger(name)
log.setLevel(logging.INFO)#设置等级
fh = logging.FileHandler(name+'.log')#设置文件处理方法
log.addHandler(fh)#绑定方法到log上
log.info('Start'.center(50,'-'))#添加log文本的头部
self.log= log#绑定到类的属性上
self.formatter = '%(func)s ->[%(time)s - %(used)s -%(ncalls)s]'#定义了输出模板 def info(self,func):#这个就是平常的装饰器
def wrapper(*args,**kw):
wrapper.ncalls +=1
lt = localtime()#返回当地时间
start = time()
res = func(*args,**kw)
used = time() - start info = {}#建立info的字典
info['func'] = func.__name__
info['time'] = strftime('%x %X',lt)
info['used'] = used
info['ncalls'] = wrapper.ncalls msg = self.formatter % info#将字典映射到输入模板上
self.log.info(msg)#输出字符串
return res
wrapper.ncalls = 0#这个语句需要在这个位置的解释有待完善
return wrapper def setFromatter(self,formatter):
self.formatter = formatter def turnOn(self):
self.log.setLevel(logging.INFO) def turnOff(self):
self.log.setLevel(logging.WARN)#级别提高就不在那里输出了 cinfo1 = CallingInfo('mylog1')
cinfo2 = CallingInfo('mylog2') cinfo1.setFromatter('%(func)s ->[%(time)s -%(ncalls)s]')
cinfo2.turnOff()#这里可以看到是很方便地修改装饰器 @cinfo1.info
def f():
print 'in f' @cinfo1.info
def h():
print 'in h' @cinfo2.info
def g():
print 'in g' from random import choice
for _ in xrange(10):
choice([f,g,h])()
sleep(choice([0.5,1,1.5]))
Python168的学习笔记8的更多相关文章
- Python168的学习笔记7
关于多线程操作. 对于IO操作,如访问网站,写入磁盘这种需要时间等待响应的操作,多个cpu也几乎不能提高效率. 对于CPU密集型操作,如这个格式转换,可以通过多个cpu同时去进行. 但是对于pytho ...
- Python168的学习笔记6
如何派生内置不可变类型并修改实例化行为. 个人理解,如何派生出自己想要的类. class IntTuple(tuple): def __new__(cls,iterable): g = (x for ...
- Python168的学习笔记5
关于对csv文件的操作. python标准库中有csv的库,使用非常方便. import csv with open('pingan.csv','rb') as rf: reader = csv.re ...
- Python168的学习笔记4
关于普通文本文件的读写 python2.7中,未注明的字符都是以acsii来编码的,而要让字符能够通用,必须声明为unicode. s=u'你好',s.encode('utf8')就是指用utf8来进 ...
- Python168的学习笔记3
list.extend(),可以拓展list,a=(0,1),b=(2,3) a.extend(b),a就变成(0,1,2,3) 分割字符串(除去字符串中的,\/;之类的),如果用str.split( ...
- Python168的学习笔记2
关于for循环,其实质是利用被循环对象的__iter__,或者__getitem__属性接口,由可迭代对象得到迭代器.for循环就是不断调用.next(),直到最终捕获到stop. import re ...
- Python168的学习笔记1
在对list的条件选择有两种常用方法,直接使用filter函数,就是filter(func,sequence);另外一种就是迭代操作,类似 x for x in sequence func.这两种方法 ...
- js学习笔记:webpack基础入门(一)
之前听说过webpack,今天想正式的接触一下,先跟着webpack的官方用户指南走: 在这里有: 如何安装webpack 如何使用webpack 如何使用loader 如何使用webpack的开发者 ...
- PHP-自定义模板-学习笔记
1. 开始 这几天,看了李炎恢老师的<PHP第二季度视频>中的“章节7:创建TPL自定义模板”,做一个学习笔记,通过绘制架构图.UML类图和思维导图,来对加深理解. 2. 整体架构图 ...
随机推荐
- bzoj 4816: 洛谷 P3704: [SDOI2017]数字表格
洛谷很早以前就写过了,今天交到bzoj发现TLE了. 检查了一下发现自己复杂度是错的. 题目传送门:洛谷P3704. 题意简述: 求 \(\prod_{i=1}^{N}\prod_{j=1}^{M}F ...
- ASP.NET MVC 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁
在开发程序的过程中,稍微不注意就会隐含有sql注入的危险.今天我就来说下,ASP.NET mvc 5使用Filter过滤Action参数防止sql注入,让你代码安全简洁.不用每下地方对参数的值都进行检 ...
- MinGw 和 cygwin 的区别和联系
原创 by zoe.zhang .......................................................... 1. windows与Linux操作系统的不同 ...
- sed实例收集
url:http://blog.csdn.net/hepeng597/article/details/7852468 一.元字符集 1)^锚定行的开始 如:/^sed/匹配所有以sed开头的行. ...
- SSD固态硬盘检测工具AS SSD参数
一. 使用AS SSD Benchmark进行查看 包括了4个方面的测试(顺序读写.4K随机读写.64线程4K读写.寻道时间) AS SSD的主要测试,也是网上最常见得到测试成绩的,是它主界面上持续. ...
- Centos之文件搜索命令locate
locate命令 locate 文件名 在后台数据库中按文件名搜索,搜索速度更快 /var/lib/mlocate #locate命令所搜索的后台数据库 updatedb 更新数据库 locate搜索 ...
- ROS二进制日志包 ROS binary logger package
原文网址: 1 http://www.ros.org/news/2017/02/ros-binary-logger-package.html 2 https://github.com/CNR-ITIA ...
- PowerTool x64驱动模块逆向分析(持续更新)
比赛打完了,来继续搞了,因为那个主动防御正在写,所以想找找思路正好想到可以来逆向一下PT的驱动模块看看pt大大是怎么写的程序. PT x64版本的驱动模块是这个kEvP64.sys. 0x0 先来看看 ...
- chmod g+s 、chmod o+t 、chmod u+s:Linux高级权限管理
关于linux下权限操作chmod的一些说明!比rxw高级内容! 转载自http://blog.chinaunix.net/uid-26642180-id-3378119.html Set uid, ...
- WordPress引入css/js两种方法
WordPress引入css/js 是我们制作主题时首先面对的一个难点,任何一款主题都要加载自己的css,js,甚至很有可能还需要加载Jquery文件,网上方法特多,说法不一,我们今天借鉴wordpr ...