python 语言概览
python 脚本可以处理外部传进来的参数 即sys.argv[] ,argv[] 的使用与linux 下相同
python 本身是解释语言,可以对输入的式子求值。python 支持的对象如整数都是立即数,此外他支持复数,及对四则运算解释。
ptyhon 支持字符串,放在单/ 双引号内,字符串是数组,可以通过[i:j] 操作获得指定位置(i - j-1) 的元素。多行的字符串可以放在""" """ 中,如果其中包含了转义字符,r"""/n""" 可以让所有字符都输出。
重载的+ * 操作,可以粘合多个字符串。
python 支持的list 用[a,b,c] 来表示,可以通过[] 取对应的元素,支持多个元素赋值如 a[2:4]=[1,2] ,list 中的元素可以是不同类型的。类似于lisp ,python 中的list 可以嵌套,嵌套的list 作为一个元素。
为了遍历list 可以用for elem in list :的方式
流程控制
python 中没有{} ,使用缩进来表示代码块,而:表示一块代码的开始,取消缩进表示代码块的结束。
if x > 0 :
print 1
elif x== 0 :
print 0
else :
print - 1
条件控制
while a>0
in / not in
A and B or (not C)
类定义
class 类名:
类体
函数定义
def fun(argv,argv=x) :支持默认参数
函数体
如果函数最后的形参为**name ,则函数接收词典。如果函数形参为*name ,则函数接收一个元组或list 。*name 必须在**name 之前。
def fun (*argv,**names):
for arg in argv:
print arg
print '-' * 40
keys = names.keys()
for key in keys:
print key, ":" ,names[key]
fun( 'here are some record' ,liming = '123456' ,ligang= '123455' )
解出参数,如果参数是list 或tuple ,则可以使用* 将对象传给函数做参数。如果参数是词典( 集合) ,则使用**name 传入
def parrot (voltage, state= 'a stiff' , action= 'voom ' ):
print "-- This parrot wouldn't" , action,
print "if you put" , voltage, "volts through it." ,
print "E's" , state, "!"
d = { "voltage" : "four million" , "state" : "bleedin ' demised" , "action" : "VOOM" }
parrot(**d)
a = [ 3 , 6 ]
print range(*a)
python 支持类似Lisp 的一些特性,如lambda 表达式,支持创建匿名函数对象。
def make_incrs (n):
""" Used to increase the number of specified """ __doc___ 成员
return lambda x:x+n
inc1 = make_incrs( 1 )
print inc1( 0 )
inc2 = make_incrs( 2 )
print inc2( 0 )
对于所有的函数,都有一个__doc__ 的成员变量,可以使用print dir.__doc__ 来查看。对于我们自己定义的函数,里面的字符串可以用""" """ 标识出来。
数据类型
List :由[] 括起来的一系列元素,list 上有insert() pop() append() extend() 等操作,支持list 作为stack 和queue 使用。
python 支持函数式编程
filter(fun,lst) 返回一个lst ,其中的元素为lst 中的元素,使得fun 为真
map(fun,lst) 返回一个lst ,其中的元素为fun 作用到lst 中的每一个元素上
map(fun, lst1 ,lst2) 返回一个lst 其中的元素为fun 作用到lst1 与lst2 对应元素的结果上
reduce(fun, lst) 返回fun 作用在lst 上前两个元素的结果与余下元素的fun 的结果,即是一个递归的过程
reduce(fun,lst,val) 返回fun( reduce(fun,lst) val) 的值
List 括号 [] 提供了一种生成List 而不使用filter ,map ,及lambda 的工具
[fun(x) for x in lst if x>0 ]
[fun(x,y) for x in lst1 for y in lst2] 二重循环,计算两个集合的的元素两两的fun
List 嵌套
mat = [
[ 1 , 2 , 3 ],
[ 4 , 5 , 6 ],
[ 7 , 8 , 9 ]
]
print [ [ row[i] for row in mat ] for i in ( 0 , 1 , 2 ) ]== print zip(*mat)
del lst[m:n] del lst 删除lst 中的元素,或者是清除这个lst 对象
元组tuple :由() 括起来的一组元素
t = 1,2,'hello',[1,2,3] == (1, 2, 'hello', [1, 2, 3])
集合Set :类型为set( [e1,e2,e3] )
s1 = set('abceda') s2=set('ceddqa')
s1 与 s2 支持 | - & ^ 操作
词典dictionary :与C++ 中的map 类似使用{} 括起来
dict( [(key1,val),(key2,val)] , ... ) = { key1:val, key2:val ,...}
词典遍历: for k,v in dict.iteritem(): print k,v
枚举enumerate :
e = eunumerate(['one','two','three'])
for i,v in e: print i,v
序列比较
对比相当类型的序列,可以进行比较。如(1,2,3,4) < (1,2,4)
模块
python 里把一个单独的脚本文件看作一个模块,可以供其他脚本import 后调用其中的各种定义,模块名称为文件名,文件名后缀加.py
模块有一个属性为__name__
模块导入import sys = from sys import * 也可以只导入需要的声明如from sys import winver
在一次会话中,模块只会被导入一次,如果导入的脚本在会话中发生了变化,可能需要reload(module_name) 来重新装入。
模块的单独运行,如果模块有可能单独运行,则需要在模块结尾加入下面的语句:
if __name__ == "__main__" :
# import sys
#fun(int(sys.argv[ 1 ]))
当在命令行上执行python 时,便会将参数传递给模块文件执行,但当import 模块时,文件则不会执行。
模块的搜索路径:由PYTHONPATH 保存并初始化给sys.path 。
为了加速模块的执行速度,可以将模块编译成字节码文件,后缀为.pyc ,pyc 文件是平台无关的,可以由多台机器共享。
标准模块,如sys 的ps1 和ps2 类似SHELL ,用来调节命令提示符的显示。
dir(module) 可以用来显示一个模块中的变量名,模块,函数,如果不带参数,则列出当前环境中定义的成员。
所有的内置变量定义与__builtin__ 模块,可以用import __builtin__ dir(__built_in__) 来查看
包:packages
用来组织模块的命名空间。A.B 表示在A 空间中的B 模块。package 可以包含子package ,类似Java 的导入方式。
当前环境所导入的模块都保存在sys.modules 中。
import 包
import A.B 的方法,最后一项必须是子包或模块,而且引用B 中的名称时,必须使用完全路径如A.B.c 来进行引用。
而from package import item 时,item 即可以是模块或子包,也可以是模块中类或者函数。import 首先查看item 是否是子项,如果没有,则假定其为一个模块,并尝试加载。
有时会用from A import * 的方法,但这可能导致耗费过多的时间,因此包的作者需要在包的__init__.py 中的__all__ 条目中,列出包所包含的子条目。则当import * 时,只会找出__all__ 中所列出的模块进行加载。
包支持一个变量__path__ ,列于__init__.py 中,用于初始化一个目录列表,指出子模块或包的路径。不过并不经常使用这个功能。
输入/ 输出
str 和repr 可以将任何格式的类型转换为字符串输出。前者转换为适合人读的形式,后者转换为适合解析器读取的形式。有时二者会返回相同的形式。
通过使用string 及+ 和str 操作,你可以完全的控制行的输出行为。
另一种方式,使用% 号来操作输出
for x in range( 1 , 10 ):
print repr(x).rjust( 2 ),repr(x*x).rjust( 3 ),repr(x*x*x).rjust( 4 )
print '%2d %3d %4d' % (x,x*x,x*x*x)
函数rjust(n) 用于输出列时,右对齐,补充空格。对应有函数ljust ,而函数zfill(n) ,则在左侧补充0 来达到对齐效果。% 号的使用同C 语言中十分类似,支持%s,%f 。
有时你可能更喜欢通过名字来引用变量,形式如下:
table = { 'Sjoerd ' : 4127 , 'Jack' : 4098 , 'Dcab ' : 8637678 }
print ( 'Jack: {0[Jack]:d}; Sjoerd : {0[Sjoerd ]:d}; Dcab : {0[Dcab ]:d}' .format(table))
读写文件
fd = open('path','mode') mode 和C 的FILE 类似如,'r' 'w','rw','r+' 等
随后可以执行fd.read(size) 未指定 size 则返回整个文件。当read 到文件尾时,返回空字符串"" 。
fd.readline() 读取一行,并在行尾加上换行符。除非是最后一行没有换行符,才没有此操作。如果readline 返回空字符串,则表示到达文件尾。一个空行,由'/n' 表示。
或者直接for line in fd: print line
写文件的话执行fd.write(str(*)) 。其他的如tell() seek() close() 等操作与C 库的文件操作定义相同。
标准库pickle
用来完成对各种python 对象的字符串化,以用来表示并在机器间传输。
如果有一个对象x 和一个可写的文件对象f ,则通过pickle.dump(x,f) 就可以将对象封装到f 中,而x=pickle.load(f) ,则执行拆封操作,把文本还原为对象。
错误和异常
错误通常是语法错误引起的,在程序执行前发生,解释器会指出错误的位置和原因。异常也有不同的类型,并在执行中发生。
在python 中使用try 来包含可能出现异常的语句,随后用except 捕获异常。
可以有多个except 语句,来处理多种异常,并且在最后 一个异常语句上不指定异常名称,以捕获所有异常,但这样有可能隐藏异常的原因。可以重新抛出异常来处理这种方式。
while 1 :
try :
x=int(raw_input( 'please input an int :' ))
break
except ValueError:
print 'Not valid input try again!'
except :
print 'Unexpected error'
raise
发生异常时,可能会有一个附属值,作为异常的参数存在,这个参数是否存在及其类型,依赖于异常的类型。
在异常名( 或列表) 之后,可以为except 子句指定一个变量,这个变量绑定于一个异常实例,参数存储于实例的args 中,异常实例定义了__getitem__ 和__str__ 可直接访问异常的参数,而不用访问args 。
try :
raise Exception( 'hello' , 'world' )
except Exception, inst:
print inst.args
print inst #__str__
x,y = inst #__getitem__
print x ,y
抛出raise 异常时,可以指定异常的参数,见上例。
用户自定义异常,通常从异常类派生出来。
清理行为通常发生在finally 语句后面,而不是放在except 语句块里面。其中的语句,不管是否发生了异常,都会被执行。
当try 中发生了没有被捕获的异常时,在执行完finally 的子句后,才抛出异常。
预定义的清理行为,通过使用with 可以声明一个对象在使用完毕之后,自动进行关闭。
with open( 'myfile.txt' , 'w' ) as f:
f.write( "hello world" )
print f.readline()
Python 的作用域与命名空间
命名空间是从命名到对象的映射,当前命名空间主要是通过Python 字典实现的。以下是一些命名空间的例子:内置命名空间,模块中的全局命名,函数调用中的局部命名。不同命名空间中的命名没有任何联系。模块对象有一个只读对象__dict__ ,它返回用于实现模块命名空间的字典,它是一个属性,应该被严格限制于调试中。
属性可以是只读或者可写的。可写属性可以用del 语句删除。
当函数被调用时创建一个local 命名空间,当函数返回或有异常抛出时,此命名空间被删除。每一个递归调用都拥有自己的命名空间。 作用域是Python 程序中一个命名空间可能直接访问的正文区域,所谓直接访问是查找命名时无需引用命名前缀。在每次执行时,至少有三个命名空间的作用域是可以直接访问的:1 包含Local 命名的作用域在最内,首先被搜索;2 包含同级函数的中层作用域;3 包含内置命名的最外层作用域,最后被搜索。
如果一个名字被声明为全局的,那么所有的赋值和引用都直接针对中层作用域- 即包含此模块全局命名的作用域。从模块外访问到的所有最内层的作用域的变量都是只读的。如果写这样的变量,则会在最内部作用域中创建一个新的局部变量。
通常,Local 作用域引用当前函数内的局部名字。在函数的外面的Local 作用域引用的是模块的命名空间-- 全局作用域。一个定义于某模块中的函数,其全局作用域是此模块的命名空间,而不是此函数被调用或引用的位置。
Python 中,赋值操作总是在最里层的作用域,赋值不会复制数据,只是将命名绑定到对象,删除也是如此,只是将对象名从局部作用域的命名空间中删除。所有引入新命名的操作都作用于局部作用域,特别是import 语句或函数定义只会绑定模块或函数名到Local 作用域。
使用类
对象是类的特化,多个名字可以绑定在一个对象上,这一点类似指针。
定义类
class student :
max_cnt = 20 #类变量
def __init__ (self ,num,name):
self .no=num #对象变量
self .na=name
def getnum (self ):
return self .no
def getname (self ):
return self .na
def setnum (self ,val):
self .no=val
def setname (self ,val):
self .na=val
类支持两种操作,属性引用和实例化。类的实例化使用函数的符号,只要将对象看作是一个返回新的类实例的无参数函数即可。
__init__() 并非类的构造函数,因为在调用__init__ 时,对象已经构造完成,它只是完成对象构造完成后的一些初始化工作。
类的实例对象唯一可用的操作就是属性引用,有两种有效的属性。一种是数据属性,它不需要在类中声明,在实例中使用时就会自动生成,并且可以在不需要的时候删除它们。另一种实例所接受的引用是方法。类中所有的函数对应于类的实例中的方法。( 在Python 的术语中,类中称为函数,实例中称为方法,二者是不同的对象) 。方法的特别之处在于将实例对象作为第一个参数传给了对应的函数。
同名的数据属性会覆盖方法属性,可选的约定包括方法的首字母大写,数据属性名前缀小写。或方法使用动词,而数据属性使用名词。数据属性可以由方法引用,可可以由使用者直接引用。不可以使用纯抽象类。在Python 中没有数据隐藏的方法。客户应该小心使用数据属性,因为客户可能会因为随意修改数据而破坏了本来由方法维护的数据一致性。不过客户只需要注意避免命名冲突,就可以随意向实例中添加数据属性而不会影响方法的有效性。
类属性中的任何函数对象在类实例中都定义为方法,不是必须要将函数定义代码放在类定义中,也可将一个函数对象赋给类中的一个变量。
通过self 参数的方法属性,方法可以调用其他的方法。
继承
class A(B) 声明类A 由B 继承而来。B 应该在A 的定义之前,如果继承自其它模块的类,则需要使用Class A(module.B) :的方式来继承。在构造派生类对象时,已经记住了基类,在解析属性引用时,如果在类中找不到请求调用的属性,就搜索基类,如果基类是由别的类派生的,则递归的进行搜索。
派生类可能会覆盖基类的方法,方法调用同一个对象中的其它方法时,可能最终调用了派生类别的覆盖方法。Python 中所有的方法本质上是虚的。在派生类中覆盖方法可能想要扩充,而非替代基类中的重名方法,此时要调用基类方法,只用调用Baseclass.methon(self,arg) 即可。
多重继承
Python 支持多重继承,只要将类放在基类列表的括号中即可。在解析类属性的规则时,顺序是深度优先,从左到右。
私有变量
Python 对类的私有成员提供了有限的支持,任何形如__member 的成员都会被进行mangle ,可用来定义私有类实例和类变量、方法、以及全局变量,甚至于将其它类的实例保存为私有变量。
小漏洞:派生类和基类取相同的名字就可以使用基类的的私有变量。
杂项
使用Struct :定义一个,然后加入一组命名数据项,可以很好的实现结构的想法。
实例的方法对象也有属性:im_self 实例方法所属的对象,而im_func 是这个方法对应的函数对象。
异常也是类,一种有效的抛出异常的方法:raise Class, instance ,简单的可以raise instance
标准库概览
1 OS 库 提供与操作系统关联的函数如:chdir,exec,open,read,lseek,umask,system,waitpid,walk,fstat,fdopen 等等函
shulti 库,提供了高级的操作目录和文件的函数,如copy,copy2,copyfile,move 等
2 文件通配符glob 库,提供了一个函数用于从目录搜索中生成文件列表的函数glob
3 命令行参数 sys.argv ,stdin,stdout,stderr 属性可以向终端输出信息。
4 字符串正则匹配re 模块
5 数学math 模块及decimal 模块导入了对浮点及数学十进制运算的支持sin , log 等 ,random 库导入生成随机数的函数
6 联网urllib2,smtplib email
7 日期和时间 datatime 模块
8 数据压缩:zlib,gzip,bz2,zipfile,tarfile 等
9 性能试题:timeit 导入时间测量工具,而profile 及pstats 模块可提供针对更大代码块的时间度量工具。
10 基于xml 的RPC :xmlrpclib SimpleXMLRPCServer 模块
11 XML 的xml.doc,xml.sax 提供了XML 的文件解析功能
12 国际化由gettext,locale 和codecs 包支持
13 格式化输出 repr 及pprint 提供了对各种对象的格式化输出操作。
14 String 中的模板类,用${nama} 表示一个可以被后继改变的占位符。
15 二进制记录:struct 模块提供了pack() 与unpack() 函数用于变长二进制记录格式。
unpack('LLLHH',data[]) 将data[16] 的二进制格式以4:4:4:2:2 字节返回为了个无组
16 线程操作可以借助模块threading
17 日志库logging
18 数组array array('H/L',1,2,3) 两端链表collections 堆实现 heapq