Python 绝对简明手册
简述
1. 阅读须知
文中使用
>>>
作为会命令行中的输出信息的前缀
对于不清楚用用途的函数可以在解释器下面输入
help(函数名)
来获取相关信息
另外,自带的文档和google也是不可少的
2. 基本语法
2.1. if / elif / else
x=int(raw_input("Please enter an integer:"))#获取行输入 if x>0: print '正数'elif x==0: print '零'else: print '负数'
此外C语言中类似"xxx?xxx:xxx"在Python中可以这样写
>>>number=8>>>print "good" if 8==number else "bad" #当满足if条件时返回"good",否则返回"bad"good
2.2. in
in判断 一个数 是否在 一个集合(如:元组,列表等) 中
if 'yes' in ('y','ye','yes'):print 'ok'
2.3. for ... in
python中没有类似C中的for循环,而是使用for...in来对集合中的每一个元素进行操作
a=['cat','door','example']for x in a: print x
如果要修改a的内容,请用a的副本循环(否则不安全),如:
a=["cat","zsp007@gmail.com"]for x in a[:]: if len(x)>6:a.insert(0,x)>>>a['zsp007@gmail.com', 'cat', 'zsp007@gmail.com']
若需要得到循环的次数,参见 函数 range 的用法
2.4. break / continue
这两个的用法和C中相同
for i in range(10): if 2==i:continue #结束当前循环,进入下一步循环 if 6==i:break #跳出循环 print i
输出
01345
2.5. while / pass
while True: pass #什么也不做
2.6. is
用来比较两个变量是否指向同一内存地址(也就是两个变量是否等价) 而 == 是用来比较两个变量是否逻辑相等
a=[1,2]b=[1,2]>>> a is bFalse>>> a == bTrue
2.7. del
用于删除元素
a=[1,2,3,4,5,6] del a[0]a>>>[2,3,4,5,6] del a[2:4]a>>>[2,3,6] del a[:]a>>>[] del aa#抛出异常>>>NameError: name 'a' is not defined
2.8. try ... except ... finally / raise
try ... except用于异常处理
try: x=int(raw_input("请输入数字:"))except ValueError: #可以同时捕获多个异常,写法如except(RuntimeError,ValueError): #当输入非数字时 print"您输入不是数字"except: #省略异常名,可以匹配所有异常,慎用 passelse:#当没有异常时 print 'result=',resultfinally:#和Java中类似。一般用于释放资源,如文件,网络连接。 print 'finish'
raise用于抛出异常,可以为自定义的异常类
惯例是以Error结尾的类,同类的异常一般派生自同一个基类(如Exception)
class MyError(Exception): def __init__(self,value): self.value=value def __str__(self): return reper(self.value)
基类异常可以匹配派生类异常
try: raise Exception("spam","egg")except Exception,inst:#inst为该异常类的实例,为可选项 print type(inst) #异常的类型 print inst
3. 内建类型
3.1. None
None 表示该值不存在,比如 没有定义返回值 的函数就 返回None
3.2. Ture / False
布尔类型,Ture等价于1,False等价于0
3.3. List
>>>test=[1,2,"yes"]
3.3.1. 内建函数
append(x) 追加到链尾
extend(L) 追加一个列表,等价于+=
insert(i,x) 在位置i插入x
remove(x) 删除第一个值为x的元素,如果不存在会抛出异常
reverse() 反转序列
pop([i]) 返回并删除位置为i的元素,i默认为最后一个元素(i两边的[]表示i为可选的,实际不用输入)
index(x) 返回第一个值为x的元素,不存在则抛出异常
count(x) 返回x出现的次数
sort() 排序
例子:
>>>test=[1,2,"yes"] >>>test.append(1) #追加到链尾>>>test[1, 2, 'yes', 1] >>>test.extend([ 'no','maybe']) #追加一个列表>>>test[1, 2, 'yes', 1, 'no', 'maybe'] >>> test.insert(0,'never') #在位置0插入'never'>>> test['never', 1, 2, 'yes', 1, 'no', 'maybe'] >>> test.remove('no') #删除第一个值为"no"的元素,如果不存在会抛出异常>>> test['never', 1, 2, 'yes', 1, 'maybe'] >>> test.reverse() #反转序列>>> test['maybe', 1, 'yes', 2, 1, 'never'] >>> test.pop() #返回并删除位置为i的元素,i默认为最后一个元素'never'>>> test['maybe', 1, 'yes', 2, 1] >>> test.index('yes') #返回第一个值为'yes'的元素,不存在则抛出异常2 >>> test.count(1) #返回1出现的次数2 >>>test.sort() #排序>>> test[1, 1, 2, 'maybe', 'yes']
3.3.2. 切片
从序列中抽取一部分
>>> test=['never', 1, 2, 'yes', 1, 'no', 'maybe'] >>> test[0:3] #包括test[0],不包括test[3]['never', 1, 2] >>> test[0:6:2] #包括test[0],不包括test[6],而且步长为2['never', 2, 1] >>> test[:-1] #包括开始,不包括最后一个['never', 1, 2, 'yes', 1, 'no'] >>> test[-3:] #抽取最后3个[1, 'no', 'maybe'] >>>test[::-1] #倒序排列['maybe', 'no', 1, 'yes', 2, 1, 'never']
3.3.3. 列表推导式
可以直接通过for循环生成一个list
>>>freshfruit=[' banana ',' loganberry ']>>>[weapon.strip() for weapon in freshfruit]['banana', 'loganberry']
说明:strip()是去除字符串两端多于空格,该句是去除序列中的所有字串两端多余的空格
>>>vec=[2,4,6]>>>[3*x for x in vec if x>3][12, 18]
>>>[(x,x**2) for x in vec]#循环变量要是一个sequence,而[x,x**2 for x in vec]是错误的[(2,4),(4,16),(6,36)]
>>>vec2=[4,3,-9] >>>[x*y for x in vec for y in vec2][8, 6, -18, 16, 12, -36, 24, 18, -54] >>>[vec[i]+vec2[i] for i in range(len(vec))][6, 7, -3]
>>>[str(round(355/113.0,i)) for i in range(1,6)]#str()是转换类型为可以打印的字符#round(x,n)表示对x保留n位小数(四舍五入)['3.1', '3.14', '3.142', '3.1416', '3.14159']
3.4. 元组
一旦初始化便不能更改的数据结构,速度比list快
>>>t=1234,5567,'hello' #t=(1234,5567,'hello')的简写 >>>x,y,z=t #拆分操作可以应用于所有sequence>>>x1234 >>>u=t,(1,2,3)>>>u((1234,5567,'hello'),(1,2,3)) >>>empty=() #空元组>>>singleton='hi', #单个元素的元组,注意逗号
通过元组可以很简单的进行数据交换. 比如:
a=1b=2a,b=b,a
3.5. set
set(集合):无序不重复的元素集
>>>basket = ['apple','orange','apple','pear','apple','banana'] >>>fruit=set(basket) >>>fruitset(['orange', 'pear', 'apple', 'banana']) >>>'orange' in fruitTrue >>>a=set('abracadabew')>>>aset(['a', 'c', 'b', 'e', 'd', 'r', 'w']) >>>b=set('wajgwaoihwb')>>>bset(['a', 'b', 'g', 'i', 'h', 'j', 'o', 'w']) >>>a-b #差set(['c', 'r', 'e', 'd']) >>>a|b #并set(['a', 'c', 'b', 'e', 'd', 'g', 'i', 'h', 'j', 'o', 'r', 'w']) >>>a&b #交set(['a', 'b', 'w']) >>>a^b #(并-交)set(['c', 'e', 'd', 'g', 'i', 'h', 'j', 'o', 'r'])
3.6. dict
字典:关键字为不可变类型,如字符串,整数,只包含不可变对象的元组.
列表等不可以作为关键字.
如果列表中存在关键字对,可以用dict()直接构造字典.而这样的列表对通常是由列表推导式生成的.
>>>tel={'jack':4098,'sape':4139} >>>tel['guido']=4127 >>>tel{'sape': 4139, 'jack': 4098, 'guido': 4127} >>>tel['jack'] #如果jack不存在,会抛出KeyError4098>>>a.get("zsp",5000) #如果"zsp"为tel的键则返回其值,否则返回5000 >>>del tel['sape'] #删除键'sape'和其对应的值>>>tel.keys() #复制一份键的副本,同理tel.items()为值的副本['jack', 'guido'] >>>"jack" in tel #判断"jack"是否tel的键True>>>"zsp" not in telTrue >>>for k,v in tel.iteritems():print k,v #同理tel.iterkeys()为键的迭代器,tel.itervalues()为值的迭代器jack 4098guido 4127 >>>tel.copy() #复制一份tel{'jack': 4098, 'guido': 4127} >>> tel.fromkeys([1,2],0) #从序列生成并返回一个字典,其值为第二个参数(默认为None),不改变当前字典{1: 0, 2: 0} >>>tel.popitem() #弹出一项('jack', 4098)
4. 函数相关
4.1. 函数定义 / 参数默认值
def fib(n=2,a=1):#参数可以有默认值 """这里给函数写文档注释""" for i in range(n): print a >>>f=fib #可以用一个变量表示函数>>>f(3)111 >>>fib(a=2) #多个可选参数赋值可以直接写"参数变量名=值"来快速赋值22
4.2. Lambda函数
一种无名函数的速写法
def make_incrementor(n): return lambda x: x+n f=make_incrementor(n)#f等价于#def f(x):# return x+n
4.3. 不定长参数 *para,**para
参数格式为 *para 表示接受一个元组
为 **para 表示接受一个字典
*para要在**para之前
def test(*args,**dic): for arg in args : print arg for k,v in dic.iteritems(): print k ,':',v >>> test("yes",1,2,me="张沈鹏",where="中国") #"yes",1,2传递给元组;me="张沈鹏",where="中国"传递给字典yes12me : 张沈鹏where : 中国
4.4. @ 装饰器
@A def B:pass 等价于 def B:pass B=A(B) 即将函数B作为参数传给参数A
from time import time#测试运行时间def cost_time(func): def result(*args,**dic): beign=time() func(*args,**dic) print "cost time : ",time()-beign return result @cost_timedef show(n): for x in range(n):print x >>> show(10)0123456789cost time : 0.0469999313354
4.5. 生成器表达式
生成器表达式:类似于没有中括号的列表推导式,可用在参数中
>>>sum(i*i for i in range(10))285 >>>unique_words=set(word for line in page for word in line.split())#page为打开的文件 >>>data='golf' >>>list(data[i] for i in range(len (data)-1,-1,-1))['f','l','o','g']
4.6. yield
每次调用返回一个值,并记录当前执行位置所有的变量
def reverse(data): for index in range(len(data)-1,-1,-1): yield data[index] for char in reverse("golf"): print char,
输出
f l o g
5. 常用函数
5.1. eval
对字符串参数运算,求值
>>> eval("1 + 2*3") #可以方便的用来做四则运算7>>> a=1>>> eval('a+1') #可以访问变量2
5.2. exec
将字符串参数作为python脚本执行
>>> exec('a="Zsp"')>>> a'Zsp'
5.3. execfile
和exec类似,不过是用来打开一个文件,并作为python脚本执行
5.4. dir
显示对象的所有属性(即可以用"."操作直接访问)
>>> dir([])['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__delslice__', '__doc__', '__eq__', '__ge__', '__getattribute__', '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__setslice__', '__str__', 'append', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
5.5. help
help(类/函数) 返回相应对象的文档字符串
>>> help(vars)Help on built-in function vars in module __builtin__: vars(...) vars([object]) -> dictionary Without arguments, equivalent to locals(). With an argument, equivalent to object.__dict__.
5.6. len
返回序列/字典的长度
>>> len([1,2,3])3
5.7. print
输出字符串 用法演示:
print "Today ", #加逗号,输出后不换行 name="ZSP" print name,"cost $",10 #输出多个变量 print "hello,%s!"%name #%s 表示用str转化为字符串 for x in xrange(1,11): print '%2d %3d' % (x,x*x) #小数输出如 %5.3f
对于字典可以用变量名来直接格式化,如:
>>>table={'Sjoerd':4127,'Jack':4098,'Dcab':8637678}>>>print 'Jack:%(Jack)d; Sjoerd:%(Sjoerd)d; Dcab:%(Dcab)d' %tableJack:4098; Sjoerd:4127; Dcab:8637678
同时,函数vars()返回包含所有变量的字典,配合使用,无坚不摧!
5.8. raw_input
x=raw_input("Please enter an sentence:") #将输入的内容赋值给x
5.9. range
range(10,0,-3)#参数的含义为起点(默认为0),终点(不含终点),步长(默认为1)>>>[10,7,4,1]
和for...in配合使用
a=['cat','door','example']for i in range(len(a)):#len()函数为求序列的长度 print i,a[i]
5.10. filter
filter(function , sequence) 返回序列,为原序列中能使function返回true的值
>>>a=[1,2,3,4]>>>filter(lambda x:x%2,a)[1, 3]
5.11. map
map(function,sequence,[sequence...])
返回序列,为对原序列每个元素分别调用function获得的值.
可以传入多个序列,但function也要有相应多的参数,如
map(lambda x,y,z:x+y+z,range(1,3),range(3,5),range(5,7))
计算过程为
1+3+5=9
2+4+6=12
返回[9,12]
5.12. reduce
reduce(function,sequence,[init])
返回一个单值为,计算步骤为 :
- 第1个结果=function(sequence[0],sequence[1])
- 第2个结果=function(第1个结果,sequence[2])
- 返回最后一个计算得值
如果有init,则先调用function(init,sequence[0])
- sequence只有一个元素时,返回该元素,为空时抛出异常.
如 reduce(lambda x,y:x+y,range(3),99) 的计算为
99+0=99 => 99+1=100 => 100+2=102
返回102
注:实际使用中用内建函数sum来完成这个累加更合适,如这里等价sum(range(3),99)
5.13. zip
zip用于多个sequence的循环
questions=['name','quest','favorite color']answers=['lancelot','the holy grail','blue'] for q,a in zip(questions,answers): print 'What is your %s ? It is %s.'%(q,a)
输出:
What is your name ? It is lancelot.What is your quest ? It is the holy grail.What is your favorite color ? It is blue.
5.14. reversed反向循环
for i in reversed(range(1,4)): print i
输出:
321
5.15. sorted排序
返回一个有序的新序列
>>>sorted([2,5,1,4])[1, 2, 4, 5]
5.16. enumerate 返回索引位置和对应的值
for i,v in enumerate(['tic','tac','toe']) print i,v
输出:
0 tic1 tac2 toe
5.17. open/文件操作
f=open('/tmp/hello','w')
#open(路径+文件名,读写模式)
#读写模式:r只读,r+读写,w新建(会覆盖原有文件),a追加,b二进制文件.常用模式
如:'rb','wb','r+b'等等
f.read([size]) size未指定则返回整个文件,如果文件大小>2倍内存则有问题.f.read()读到文件尾时返回""(空字串)
file.readline() 返回一行
file.readline([size]) 返回包含size行的列表,size 未指定则返回全部行
for line in f: print line #通过迭代器访问
f.write("hello\n") #如果要写入字符串以外的数据,先将他转换为字符串.
f.tell() 返回一个整数,表示当前文件指针的位置(就是到文件头的比特数).
f.seek(偏移量,[起始位置])
用来移动文件指针
偏移量:单位:比特,可正可负
起始位置:0-文件头,默认值;1-当前位置;2-文件尾
f.close() 关闭文件
6. 模块化
6.1. 导入模块
模块的查找路径
1.当前的目录
2.环境变量PYTHONPATH所指的目录列表
3.python解释器的安装目录
如将代码保存上述的一个目录中的的fibo.py文件中,便可以
import fibofibo.function()
如果想直接使用fibo.function可以重命名这个函数,如
f=fibo.functionf()
也可以
form fibo import functionfunction()
甚至可以form fibo import *
可以 form 包.子包.模块 imort 函数
然后就直接使用该函数,不需要加前缀
6.2. 包
引用推荐写法为
form 包 import 模块
几个功能类似的模块可以组合成一个包,
比如一个可以处理.wav,.mp3,.wma等音频文件的有类似如下结构:
Sound/ __init__.py Formats/ __init__.py wavread.py wavwrite.py mp3read.py mp3write.py wmaread.py wmawrite.py Effects/ __init__.py echo.py surround.py reverse.py
只有当init.py存在时python才将该文件夹视为一个包.
该文件可以为空文件 一般在init.py文件中定义一个all列表,包含要import *时要导入的模块. 如Sound/Effects/init.py可以有如下内容
__all__=["echo","surround","reverse"]
包的作者在发布包时可以更新这个列表,也可以根据需要让某个模块不支持import *
对于包中同一个文件夹下的模块可以把
form 包.子包 imort 模块
简写为 imort 模块
6.3. 面向对象
6.3.1. 概要
class ClassName: "类文档,可以通过类名.__doc__访问" def f(self):#self为每个类函数的必要的一个参数,可以通过它来访问当前实例 return self.content def __init__(self,word=''):#构造函数 #构造函数,可以初始化变量,可以有参数" self.content=word self.__name=word #私有变量,以"__"开头,不以"__"结尾的变量
创建类实例 x=ClassName("good")
6.3.2. 类继承
class DerivedClassName(BassClassName):
- pass
如果基类定义在另一个模块中, 要写成
modname.BaseClassName
派生类的函数会覆盖基类的同名函数
如果想扩充而不是改写基类的函数,可以这样调用基类函数
BaseClassName.methodname(self,arguments)
注意:该基类要在当前全局域或被导入
class A: def hi(self): print "A"class B: def hi(self): A.hi(self) super(B).hi() #通过super关键字可以获得当前类的基类 print "B" B().hi()
输出
AB
6.3.3. 多重继承
类多继承
class DerivedClassName(Base1,Base2,Base3): pass
对于该类函数的解析规则是深度优先,先是Base1,然后是Base1的基类,诸如此类.
class A: def hi(self): print "A" class B: def hi(self): print "B" class C(A,B): pass C().hi()
输出:
A
6.4. 操作符重载
通过定义类的一些约定的以""开头并结尾的函数,可以到达重载一些特定操作的目的,下面是是一些常用的重载
6.4.1. __str__ / __unicode__
当print一个对象实例时,实际是print该实例
str()函数的返回值.
class A: def __str__(self): return "A" def __unicode__(self): return "uA" print A()print unicode(A())
输出
AuA
unicode和str类似,不过返回Unicode字符串.
6.4.2. 比较操作
x<y x.
lt(y)
x<=y x.
le(y)
x==y x.
eq(y)
x!=y 或 x<>y x.
ne(y)
x>y x.
gt(y)
x>=y x.
ge(y) cmp( self, other) 用来简化比较函数的定义 self < other返回负数,相等时返回0,self>other时返回正数
class A: def __init__(self,i): self.i=i def __cmp__(self,other): return self.i-other.i print A(1)>A(2)
输出
False
6.4.3. __iter__
for ... in 循环即就是通过这个函数遍历当前容器的对象实例 可配合yield方便的编写这个函数(参见基本语法yield)
class A: def __init__(self,n): self.n=n def __iter__(self): n=self.n while n: m=n%2 n/=2 yield m for i in A(5): print i,
输出
1 0 1
另有一种繁琐的实现: 返回一个可以通过next()函数遍历的对象,当结束时抛出StopIteration异常
6.5. 类相关函数
6.5.1. type
返回对象的类型
>>> type("")<type 'str'>>>> type("")==strTrue >>> type([])<type 'list'>>>> type([])==listTrue >>> type({})<type 'dict'> >>> type(())<type 'tuple'> >>> class A:pass >>> type(A)<type 'classobj'> >>> type(A())<type 'instance'> >>> import types #在types模块中有许多类型的定义 >>> type(A)==types.ClassTypeTrue
6.5.2. getattr / hasattr /delattr
getattr:通过类实例和一个字符串动态的调用类函数/属性
class A: def name(self): return "ZSP" def hello(self): return "nice to meet me ." def say(obj,attr): print getattr(obj,attr)() a=A()say(a,"name")say(a,"hello")
输出
ZSPnice to meet me .
hasattr 用来判断实例有无该函数/属性
delattr 用来删除实例的函数/属性
6.5.3. property
通过值的方式调用实例无参函数
class A(object): def __init__(self): self._x = None def getx(self): return self._x def setx(self, value): self._x = value def delx(self): self._x=None x = property(getx, setx, delx, "I'm the 'x' property.")a=A()print a.x a.x="ZSP"print a.x del a.xprint a.x
输出
NoneZSPNone
可以方便的定义一个只读属性
class A(object): @property def x(self): return "Property"
调用
>>>a=A() >>>print a.xProperty >>>a.x="ZSP" #只读属性,不能更改Traceback (most recent call last): File "D:\Profile\Untitled 2.py", line 9, in <module> a.x="ZSP"AttributeError: can't set attribute
6.5.4. isinstance( object, classinfo)
判断一个对象是否是一个类的实例
>>>class A:pass >>>class B:pass >>>a=A() >>>isinstance(a,A)True >>>isinstance(a,B)False
Python 常用模块体验 ::-- ZoomQuiet [2007-11-10 06:37:48]
目录
- Py常用模块汇编
- zshelve 对象持久模块
- 发布
- 补丁::
- fast UserDict
- zshelve 对象持久模块
CPUG联盟:: |
CPUG::门户plone |
BPUG |
SPUG |
ZPUG |
SpreadPython Python宣传 |
7. Py常用模块汇编
'Python 标准库2.0 整理者
Python 江湖 QQ 群: 43680167Feather (校对) gt: andelf@gmail.com
一些有用的Python函式庫列表 » 程式設計 遇上 小提琴
::-- ZoomQuiet [2007-11-10 07:39:01]
CPUG联盟:: |
CPUG::门户plone |
BPUG |
SPUG |
ZPUG |
SpreadPython Python宣传 |
7.1. zshelve 对象持久模块
{{{Jiahua Huang <jhuangjiahua@gmail.com> reply-to python-cn@googlegroups.com, to "python. cn" <python-cn@googlegroups.com>, date Nov 8, 2007 5:41 PM subject [CPyUG:34726] 贴个 zlib 压缩的 zshelve 对象持久模块 }}} 这个给 Python 标准库的 shelve.py 添加了 zlib 压缩, 减小数据库文件体积,以改善磁盘 io 性能
7.1.1. 发布
http://zshelve.googlecode.com/svn/trunk/
加了个命令行工具:
huahua@huahua:tmp$ zshelvecommandline tool for zshelve databases Usage: zshelve FILE dump Dump the data tree zshelve FILE keys List of keys zshelve FILE get KEY Dump value for key zshelve FILE set KEY VALUE Set db[key] = value zshelve FILE has_key KEY True if database has the key zshelve FILE search_key KEY Search key zshelve FILE search_value VALUE Search value huahua@huahua:tmp$ zshelve set tes.db a 1huahua@huahua:tmp$ zshelve dump tes.db |- a | | - 1huahua@huahua:tmp$ zshelve set tes.db b "dict(a=1,b=2,c=3,d={'s':'4'})"huahua@huahua:tmp$ zshelve dump tes.db |- a | |- 1 |- b | |- a | | |- 1 | |- c | | |- 3 | |- b | | |- 2 | |- d | | |- s | | | |- 4
对比::
>>> import zshelve>>> import shelve>>> zdb = zshelve.open('/tmp/zshelve.db')>>> db = shelve.open('/tmp/shelve.db')>>> zdb['1'] = dict(a='0123456789'*10000000)>>> db['1'] = dict(a='0123456789'*10000000)>>> zdb.sync()>>> db.sync()
看看文件大小差异::
huahua@huahua:zshelve$ ll /tmp/*shelve.db-rw-r--r-- 1 huahua huahua 96M 2007-11-08 17:36 /tmp/shelve.db-rw-r--r-- 1 huahua huahua 204K 2007-11-08 17:36 /tmp/zshelve.db
7.1.2. 补丁::
--- shelve.py 2007-05-03 00:56:36.000000000 +0800+++ zshelve.py 2007-11-08 17:25:59.000000000 +0800@@ -70,6 +70,7 @@ except ImportError: import UserDict import warnings+import zlib ## use zlib to compress dbfile __all__ = ["Shelf","BsdDbShelf","DbfilenameShelf","open"] @@ -80,13 +81,14 @@ class Shelf(UserDict.DictMixin): See the module's __doc__ string for an overview of the interface. """ - def __init__(self, dict, protocol=None, writeback=False):+ def __init__(self, dict, protocol=None, writeback=False, compresslevel=2): self.dict = dict if protocol is None: protocol = 0 self._protocol = protocol self.writeback = writeback self.cache = {}+ self.compresslevel = compresslevel def keys(self): return self.dict.keys()@@ -109,7 +111,7 @@ class Shelf(UserDict.DictMixin): try: value = self.cache[key] except KeyError:- f = StringIO(self.dict[key])+ f = StringIO(zlib.decompress(self.dict[key])) value = Unpickler(f).load() if self.writeback: self.cache[key] = value@@ -121,7 +123,7 @@ class Shelf(UserDict.DictMixin): f = StringIO() p = Pickler(f, self._protocol) p.dump(value)- self.dict[key] = f.getvalue()+ self.dict[key] = zlib.compress(f.getvalue(), self.compresslevel) def __delitem__(self, key): del self.dict[key]@@ -168,32 +170,32 @@ class BsdDbShelf(Shelf): See the module's __doc__ string for an overview of the interface. """ - def __init__(self, dict, protocol=None, writeback=False):- Shelf.__init__(self, dict, protocol, writeback)+ def __init__(self, dict, protocol=None, writeback=False, compresslevel=2):+ Shelf.__init__(self, dict, protocol, writeback, compresslevel) def set_location(self, key): (key, value) = self.dict.set_location(key)- f = StringIO(value)+ f = StringIO(zlib.decompress(value)) return (key, Unpickler(f).load()) def next(self): (key, value) = self.dict.next()- f = StringIO(value)+ f = StringIO(zlib.decompress(value)) return (key, Unpickler(f).load()) def previous(self): (key, value) = self.dict.previous()- f = StringIO(value)+ f = StringIO(zlib.decompress(value)) return (key, Unpickler(f).load()) def first(self): (key, value) = self.dict.first()- f = StringIO(value)+ f = StringIO(zlib.decompress(value)) return (key, Unpickler(f).load()) def last(self): (key, value) = self.dict.last()- f = StringIO(value)+ f = StringIO(zlib.decompress(value)) return (key, Unpickler(f).load()) @@ -204,12 +206,12 @@ class DbfilenameShelf(Shelf): See the module's __doc__ string for an overview of the interface. """ - def __init__(self, filename, flag='c', protocol=None, writeback=False):+ def __init__(self, filename, flag='c', protocol=None,writeback=False, compresslevel=2): import anydbm- Shelf.__init__(self, anydbm.open(filename, flag), protocol, writeback)+ Shelf.__init__(self, anydbm.open(filename, flag), protocol,writeback, compresslevel) -def open(filename, flag='c', protocol=None, writeback=False):+def open(filename, flag='c', protocol=None, writeback=False, compresslevel=2): """Open a persistent dictionary for reading and writing. The filename parameter is the base filename for the underlying@@ -222,4 +224,4 @@ def open(filename, flag='c', protocol=No See the module's __doc__ string for an overview of the interface. """ - return DbfilenameShelf(filename, flag, protocol, writeback)+ return DbfilenameShelf(filename, flag, protocol, writeback, compresslevel)
一行代码让 UserDict.UserDict 的类加速 4 倍
::-- ZoomQuiet [2007-11-10 07:34:49]
目录
- fast UserDict
7.2. fast UserDict
{{{Jiahua Huang <jhuangjiahua@gmail.com> reply-to python-cn@googlegroups.com, to "python. cn" <python-cn@googlegroups.com>, date Nov 10, 2007 3:28 PM subject [CPyUG:34791] 一行代码让 UserDict.UserDict 的类加速 4 倍 }}} 发现 Python 标准库里好些字典类从 UserDict.UserDict 派生, 而不是从 dict 派生, 是因为 旧版 python 内建类型不能派生子类,
那么这会不会影响速度呢,
先给两个分别继承 UserDict.UserDict 和 dict 的类 URdict, Rdict
>>> import UserDict>>> class URdict(UserDict.UserDict):... '''dict can search key by value... '''... def indexkey4value(self, value):... '''search key by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.indexkey4value('Other')... 'b'... '''... try:... ind = self.values().index(value)... return self.keys()[ind]... except:... return None... def key4value(self, svalue):... '''search key by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.key4value('Other')... 'b'... '''... for key, value in self.iteritems():... if value == svalue:... return key... def keys4value(self, svalue):... '''search keys by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.keys4value('Other')... ['b', 'e']... '''... keys=[]... for key, value in self.iteritems():... if value == svalue:... keys.append(key)... return keys...>>>>>> class Rdict(dict):... '''dict can search key by value... '''... def indexkey4value(self, value):... '''search key by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.indexkey4value('Other')... 'b'... '''... try:... ind = self.values().index(value)... return self.keys()[ind]... except:... return None... def key4value(self, svalue):... '''search key by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.key4value('Other')... 'b'... '''... for key, value in self.iteritems():... if value == svalue:... return key... def keys4value(self, svalue):... '''search keys by value... >>> rd = Rdict(a='One', b='Other', c='What', d='Why', e='Other')... >>> rd.keys4value('Other')... ['b', 'e']... '''... keys=[]... for key, value in self.iteritems():... if value == svalue:... keys.append(key)... return keys...>>> >>> import time>>> def _timeit(_src):... exec('''... _t0 = time.time()... %s... _t1 = time.time()... _t3 = _t1 - _t0... '''%_src)... return _t3...>>> ran = range(100000) 再弄俩实例>>> u = URdict()>>> r = Rdict() 看看插入速度>>> _timeit("for i in ran: u[i]=i")0.1777961254119873>>> _timeit("for i in ran: r[i]=i")0.048948049545288086 看看原始 dict 的速度>>> _timeit("for i in ran: d[i]=i")0.041368961334228516
可以看到, UserDict.UserDict 确实严重影响速度,
python 标准库里边好多 UserDict 的都应该换成 dict , 以提高性能
不过,一个个修改 Python 标准库似乎又不合适,
再次使用一招鲜,直接干掉 UserDict
在使用/导入那些模块前先来一行
>>> import UserDict; UserDict.UserDict = dict
完了再导入模块来试试
>>> u = URdict()>>> _timeit("for i in ran: u[i]=i")0.042366981506347656
一行代码让速度提高 4 倍
转载于:https://www.cnblogs.com/end/archive/2011/04/27/2030946.html
Python 绝对简明手册相关推荐
- Python简明手册-转自啄木鸟社区
Python 绝对简明手册 -- zsp007@gmail.com ::-- ZoomQuiet [2006-09-15 04:35:33] Contents 阅读须知 基本语法 if / elif ...
- python代码没有反应_没有任何编程经验者不要被Python简明手册误导。
想学python,没有任何编程经验者不要被python简明手册误导. 1.python简明手册是一本好书 但这本书是针对有经验的程序员看的,详细一点说,有3年以上c++/java,.delphi/vb ...
- python使用手册-python 教程与手册(60IN1合集)
python 教程与手册(60IN1合集)1个豆 下载地址: CGI介绍及使用Python来开发CGI应用示例.pdf dive into python Django绝对简明教程.pdf Gray H ...
- chef之cookbook入门简明手册
本手册基于markdown编写,因为论坛不能删除markdown文件,压缩后,由不方便故这里上传生成后的pdf(),令附上,markdown内容,方便大家自行修改编辑 ================ ...
- 转载 Org-mode 简明手册
转载来自: https://www.cnblogs.com/Open_Source/archive/2011/07/17/2108747.html#sec-4-1 Org-mode 简明手册 UP | ...
- Org-mode 简明手册
Org-mode 简明手册 Table of Contents 1 简介 1.1 序 1.2 安装 1.3 激活 1.4 反馈 2 文档结构 2.1 大纲 2.2 标题 2.3 视图循环 2.4 移动 ...
- python语言教程-Python语言教程手册
Python语言教程手册 Python是什么? 解释性语言 多范式 介绍 命令后>>>python Python 2.7.3 (default, Aug 1 2012, 05:14: ...
- Python类简明教程
Python类简明教程
- 【赠书】迁移学习如何入门,看看这本简明手册即可
相信很多学迁移学习的同学都阅读过知乎上的<小王爱迁移>系列文章或在GitHub上开源发布的迁移学习简明手册,手册上线已逾3年,帮助了众多读者快速入门迁移学习,现在这本手册已全面更新, ...
- 火爆全网的迁移学习简明手册全面更新,重磅出版上市!(送书!)
学习迁移学习的小伙伴大都应该读过知乎上的<小王爱迁移>系列文章或在GitHub上开源发布的迁移学习简明手册: https://zhuanlan.zhihu.com/p/35352154 & ...
最新文章
- SecureCRT连接虚拟机
- Ext.Net学习笔记18:Ext.Net 可编辑的GridPanel
- 2021-01-20 Python编程特殊小技巧汇集
- 嵌入式笔录(4)-LC并联电路选频和AM解调
- java没有打印mysql日志_0216 aop和打印数据库执行日志
- elasticsearch全局analyzer声明
- python 第三方模块之 APScheduler - 定时任务
- CentOS下的sudo相关配置的总结归纳
- Linux将文件复制粘贴到另外一个位置
- JDKAndroid下载安装
- 基尼不纯度(Gini impurity)
- R语言计算回归模型R方(R-Squared)实战
- Java零基础学习记录09(飞机躲避炮弹游戏实现)
- Faster-Rcnn 网络训练医学乳腺DDSM图像不能预测到定位框问题及其训练问题
- 入职阿里一年,年收入过百万,网友:阿里快人均百万了?
- 十一、SpringCloud实用篇_Gateway服务网关
- appinventor认识
- PowerMock简介及常见注解解释
- python为啥爬取数据会有重复_利用Python来爬取“吃鸡”数据,为什么别人能吃鸡?...
- 当代年轻人下班行为报告:我下班了,却又没完全下班
热门文章
- 梅花传播业大展:Focussend将精准营销融入个性化邮件
- 批量获取客户端时间偏差
- 【原】unity3D之Draw Call
- 学习language C
- vscode 格式化某一段代码_vscode 如何自动格式化代码?
- python 遍历数组gbk编码_python bytes和bytearray、编码和解码
- 拉取远程分支到本地分支_想买的保险本地没有分支机构怎么办?异地投保理赔难吗?...
- 应用动态html教学反思,12月份教学反思:百分数的应用(一)反思
- html中展开的小箭头,HTML5 移动网页应用中的展开式标签(带上下指示箭头)
- 对象关系映射文件详解