一:基础总结
(1)文件I/O 非常类似于 C语言 ;IO在计算机中指Input/Output,也就是输入和输出。由于程序和运行时数据是在内存中驻留,由CPU这个超快的计算核心来执行,涉及到数据交换的地方,通常是磁盘、网络等,就需要IO接口。
spath= "D:/download/baa.txt" f=open(spath,"w" ) f.write("First line 1.\n" ) f.writelines("First line 2." ) f.close() f=open(spath,"r" ) for line in f: print line f.close()
(2)异常处理 try: except: 在程序运行的过程中,如果发生了错误,可以事先约定返回一个错误代码,这样,就可以知道是否有错,以及出错的原因。在操作系统 提供的调用中,返回错误码非常常见。比如打开文件的函数 open()
,成功时返回文件描述符(就是一个整数),出错时返回 -1
。
s=raw_input( "Input your age:" ) if s =="": raise Exception( "Input must no be empty." ) try : i=int(s) except ValueError: print "Could not convert data to an integer." except : print "Unknown exception!" else : print "You are %d" % i, " years old" finally : print "Goodbye!"
(3)类和继承 class B (A)的形式类是创建实例的模板,而实例则是一个一个具体的对象,各个实例拥有的数据都互相独立,互不影响; 方法就是与实例绑定的函数,和普通函数不同,方法可以直接访问实例的数据;通过在实例上调用方法,我们就直接操作了对象内部的数据,但无需知道方法内部的实现细节。
(4)包机制 每一个.py文件称为一个module,module之间可以互相导入.请参看以下例子: # a.py def add_func(a,b): return a+b # b.py from a import add_func # Also can be : import a print "Import add_func from module a" print "Result of 1 plus 2 is: " print add_func(1,2) # If using "import a" , then here should be "a.add_func"
二:实战例子
import re class Parent: parentAttr = 100 ; def __init__( self ): print "调用父类构造函数 Parent construct" .decode( "utf-8" ).encode( "gbk" ); def parentMethod( self ): print "调用父类成员函数:Parent method" ; def setAttr( self ,attr): Parent.parentAttr = attr; def getAttr(sef): print "父类属性:ParentAttr:" , Parent.parentAttr; def __del__( self ): print "parent descontruct" ; class Child(Parent): def __init__( self ): print "调用子类构造方法 child construct" def childMethod( self ): print '调用子类方法 child method' def __del__( self ): print "child destructor" ; c = Child() c.childMethod() c.parentMethod() c.setAttr(200 ) c.getAttr() lines = "zyp,0001,nan\r\nxqz,0002,nan\r\nwzx,0003,nv" ; line = "Cats are smarter than dogs" ; matchObj = re.match( r'(.*),' , lines, re.M|re.I) if matchObj: print "ddd" , matchObj.group(); else : print "no match!!" ; lists = lines.split(',\\r\\n' ); print "lists:" ,lists; for li in lists: print li; print " *********just for test******" ; try : fileR = open('splits.txt' , 'r' ); done = 0 ; while not done: f_str = fileR.readline(); if (f_str != '' ): eles = f_str.split(',' ); for ele in eles: print ele; else : done = 1 ; except IOError: print "Error:can\'t find this file" ; fileR.close(); print " *********just for test******" ; try : fileR = open('splits.txt' , 'r' ); f_lines = fileR.readlines(); for line in f_lines: eles = line.split(',' ); for ele in eles: print ele; except IOError: print "Error:can\'t find this file" ; fileR.close();
说明:本例子说明了Python的类继承,以及异常处理,和文件的读取任务
三:易犯错误
(1)常见错误1:在函数参数中乱用表达式作为默认值
Python 允许给一个函数的某个参数设置默认值以使该参数成为一个可选参数。尽管这是这门语言很棒的一个功能,但是这当这个默认值是可变对象(mutable)时,那就有些麻烦了。例如,看下面这个Python函数定义:
def foo(bar=[]): bar.append("MKY" ); return bar; print foo() print foo()
答案是一个函数参数的默认值,仅仅在该函数定义的时候,被赋值一次。如此,只有当函数foo()第一次被定义的时候,才讲参数bar的默认值初始化到它的默认值(即一个空的列表)。当调用foo()的时候(不给参数bar),会继续使用bar最早初始化时的那个列表。
(2)本地变量(由于赋值和变量不用声明即可用造成的)在使用列表 (lists)的时候,这种情况尤为突出。看下面这个例子:
>>> lst = [ 1 , 2 , 3 ] >>> def foo1(): ... lst.append(5 ) ... >>> foo1() >>> lst [1 , 2 , 3 , 5 ] >>> lst = [1 , 2 , 3 ] >>> def foo2(): ... lst += [5 ] ... >>> foo2() Traceback (most recent call last): File "<stdin>" , line 1 , in <module> File "<stdin>" , line 2 , in foo UnboundLocalError: local variable 'lst' referenced before assignment
嗯?为什么foo2有问题,而foo1没有问题?
答案foo1并没有给lst赋值,但是foo2尝试给lst赋值。注意lst+=[5]只是lst=lst+[5]的简写,由此可以看到我们尝试给lst赋值(因此Python假设作用域为本地)。但是,这个要赋给lst的值是基于lst本身的(这里的作用域仍然是本地),而lst却没有被定义,这就出错了。
(3)与Python标准库模块命名冲突
Python的一个优秀的地方在于它提供了丰富的库模块。但是这样的结果是,如果你不下意识的避免,很容易你会遇到你自己的模块的名字与某个随Python附带的标准库的名字冲突的情况(比如,你的代码中可能有一个叫做email.py的模块,它就会与标准库中同名的模块冲突)。
这会导致一些很粗糙的问题,例如当你想加载某个库,这个库需要加载Python标准库里的某个模块,结果呢,因为你有一个与标准库里的模块同名的模块,这个包错误的将你的模块加载了进去,而不是加载Python标准库里的那个模块。这样一来就会有麻烦了。
所以在给模块起名字的时候要小心了,得避免与Python标准库中的模块重名。相比起你提交一个“Python改进建议(Python Enhancement Proposal (PEP))”去向上要求改一个标准库里包的名字,并得到批准来说,你把自己的那个模块重新改个名字要简单得多。