第十一章:文件和素材
1:打开文件——open函数用来打开文件:open(name[, mode[, buffering]])
f = open(r'C:\text\somefile.txt')
'+'参数可以用到其他任何模式中,指明读和写都是允许的。比如'r+'能在打开一个文本文件用来读写时使用
'b'模式改变处理文件的方法。一般的,python假定处理的是文本文件(包含字符)。但如果处理的是一些其他类型的文件(二进制文件),如声音剪辑或图像,那么应该在模式参数中增加'b'。'rb'可以用来读取一个二进制文件
2)缓冲:open函数的第三个参数(可选)控制着文件的缓冲。如果参数是0(或是False),I/O(输入/输出)就是无缓冲的(所有的读写操作都直接针对硬盘);如果是1(或True),I/O就是有缓冲的(意味着Python使用内存来代替硬盘,让程序更快,只有使用flush或close时才会更新硬盘上的数据)。大于1的数字代表缓冲区的大小(单位是字节),-1(或任何负数)代表使用默认的缓冲区大小
2:基本文件方法——介绍文件对象(和一些类文件对象,有时成为六)的一些基本方法
类文件对象是支持一些文件的方法的对象,比如file方法,更重要的是支持read方法或者write方法,或者两者兼有。那些由urllib.urlopen返回的对象是一个很好的例子。
三种标准的流:它们实际上是文件(或者是类文件对象)。大部分文件对象可用的操作它们也可以使用
数据输入的标准源是sys.stdin。当程序从标准输入读取数据时,你可以通过输入或者使用管道把它和其他程序的标准输出链接起来提供文本(管道是标准的UNIX概念)。要打印的文本保存在sys.stdout。input函数的提示文字也是写在sys.stdout中。写入sys.stdout的数据一般是出现在屏幕上,但也能使用管道连接到其他程序的标准输入。错误信息(如栈追踪)被写入sys.stderr
1)读和写:文件(或流)最重要的能力是提供或接受数据:f.write(string)将string追加到文件中。f.read()默认是r模式
2)管式输出:在UNIX的shell(就像GNU bash)中,使用管道可以在一个命令后面续写其他的多个命令,就像:
$ cat somefile.txt | python somescript.py | sort
这个管道(pipeline)由以下3个命令组成:
A:cat somefile.txt:只是把somefile.txt的内容写到标准输出(sys.stdout)
B:python somescript.py:这个命令运行了python脚本somescript。脚本应该是从标准输入读,把结果写入到标准输出
C:sort:这个命令把从标准输入(sys.stdin)读取所有的文本,按字母排序,然后把结果写入标准输出
管道符号(|)的作用是将一个命令的标准输出和下一个命令的标准输入连在一起。这样,somescript.py会从它的sys.stdin中读取数据(cat somefile.txt写入的),并把结果写入它的sys.stdout(sort在此得到数据)中。
#somescript.py import sys text = sys.stdin.read() words = text.split() wordcount = len(words) print('Wordcount:'.wordcount) #下面是cat somefile.txt | python somescript.py的结果
在文件中随意移动读取位置是可以的,可以使用类文件对象seek和tell来直接访问感兴趣的部分(这种做法称为随机访问):
seek(offset [, whence]):这个方法把当前位置(进行读和写的位置)移动到由offset定义的位置。whence默认是0,也就是说偏移量是从文件开头开始计算的(偏移量必须是非负的)。whence可能被设置为1(相对于当前位置的移动,offset可以是负的)或者2(相对于文件结尾的移动)
>>> f=open(r'd:\pythontest.txt','w') >>> f.write('01234567890123456789') 20 >>> f.seek(5) 5 >>> f.write('Hello,world!') 12 >>> f.close() >>> f=open(r'd:\pythontest.txt') >>> f.read() '01234Hello,world!789'
tell方法返回当前文件的位置:
>>> f=open(r'd:\pythontest.txt') >>> f.read(3) '012' >>> f.read(2) '34' >>> f.tell() 5
3)读写行:
可以使用file.readline读取单独的一行(从当前的位置开始直到一个换行符出现,也读取这个换行符)。不使用任何参数(这样,一行就被读取和返回)或者使用一个非负的整数作为readline可以读取的字符(或字节)的最大值。因此,如果somefile.readline()返回'Hello,World!\n',somefile.readline(5)返回'Hello'。readlines方法可读取一个文件中的所有行并将其作为列表返回。
writelines方法和readlines相反:传给它一个字符串的列表(实际上任何序列或可迭代的对象都行),它会把所有的字符串写入文件(或流)。注意,程序不会增加新行,需要自己添加。没有writeline方法,因为能使用write
注意:在使用其他的符号作为换行符的平台上,用"\r"(Mac)和"\r\n"(windows)代替"\n"
4)关闭文件:close方法
5)使用基本文件方法
#read(n) f=open(r'd:\somefile.txt') >>> f.read(7) 'Welcome' >>> f.read(4) ' to ' >>> f.close() #read() >>> f=open(r'd:\somefile.txt') >>> print(f.read()) Welcome to this file There is nothing here except This stupid haiku #readline() >>> f=open(r'd:\somefile.txt') >>> for i in range(3): print(str(i) + ': ' + f.readline()) 0: Welcome to this file 1: There is nothing here except 2: This stupid haiku >>> f.close() #readlines() >>> import pprint >>> pprint.pprint(open(r'd:\somefile.txt').readlines()) ['Welcome to this file\n', 'There is nothing here except\n', 'This stupid haiku'] #write(string) >>> f=open(r'd:\somefile.txt','w') >>> f.write('this\nis no\nhaiku') 16 >>> f.close() #'this\nis no\nhaiku' #writelines(list) >>> f=open(r'd:\somefile.txt') >>> lines=f.readlines() >>> f.close() >>> lines[1] = "isn't a\n" >>> f=open(r'd:\somefile.txt','w') >>> f.writelines(lines) >>> f.close() #'this\nisn't a\nhaiku'
3:对文件内容进行迭代
1)按字节处理:最常见的对文件内容进行迭代的方法是在while循环中使用read方法:
def process(string): print('Processing:'.string) f=open(filename) char = f.read(1) while char: process(char) char=f.read(1) f.close()
这个程序可以使用是因为当文件到达末尾时,read方法返回一个空的字符串(False)。可以看到,赋值语句char=f.read(1)被重复使用,应该避免这种情况:
f=open(filename) while True: char = f.read(1) if not char:break process(char) f.close()
2)按行操作:readline
f=open(filename) while True: line = f.readline() if not line: break process(line) f.close()
3)读取所有内容:如果文件不是很大,可以使用不带参数的read方法一次读取整个文件(把整个文件当成一个字符串来读取),或者使用readlines方法(把文件读入一个字符串列表,在列表中每个字符串就是一行)
#用read迭代每个字符 f=open(filename) for char in f.read(): process(char) f.close() #用readlines迭代行 f=open(filename) for line in f.readlines(): process(line) f.close()
4)使用fileinput实现懒惰行迭代:在需要对一个非常大的文件进行迭代行的操作时,readlines会占用太多内存。这个时候可以使用while循环和readline方法来替代。另外,在python中如果能使用for循环,那它就是首选。下例使用for循环可以使用一个名为 懒惰行迭代 的方法:说它懒惰因为它只读取实际需要的文件部分
import fileinput for line in fileinput.input(filename): process(line)
5)文件迭代器:在python近几个版本中(2.2开始),文件对象是可迭代的:
f=open(filename) for line in f: process(line) f.close()
对文件进行迭代而不使用变量存储文件对象:
for line in open(filename): process(line)
注意sys.stdin是可迭代的,就像其他文件对象。因此如果想要迭代标准输入中的所有行,可按如下形式使用sys.stdin:
import sys for line in sys.stdin: process(line)
可以对文件迭代器执行和普通迭代器相同的操作。比如将它们转换为字符串列表(使用list(open(filename)),这样所达到的效果和使用readlines一样
>>> f=open(r'd:\somefile.txt','w') >>> f.write('First line\n') 11 >>> f.write('Second line\n') 12 >>> f.write('Third line\n') 11 >>> f.close() >>> lines=list(open(r'd:\somefile.txt')) >>> lines ['First line\n', 'Second line\n', 'Third line\n'] >>> first,second,third = open(r'd:\somefile.txt') >>> first 'First line\n' >>> second 'Second line\n' >>> third 'Third line\n'
上面的例子中,需要注意以下几点:
A:使用print来向文件写入内容,这会在提供的字符串后面增加新的行
B:使用序列来对一个打开的文件进行解包操作,把每行都放入一个单独的变量中(这么做是很有实用性的,因为一般不知道文件中有多少行)
C:在写文件后关闭了文件,是为了确保数据被更新到硬盘
小结
类文件对象:类文件对象是支持read和readline方法(可能是write和writelines)的非正式对象
打开和关闭文件、模式和文件类型:open、close、r......
标准流:3个标准文件对象(sys模块中的stdin、stdout和stderr)是一个类文件对象,该对象实现了UNIX标准的I/O机制
读和写:read和write方法可对文件对象或类文件对象进行读写操作
读写行:readline和readlines读取行、writelines写入数据
迭代文件内容:一般是迭代文本中的行,通过迭代文件对象本身可以轻松完成
第十二章:图形用户界面
1:wxPython下载和安装——如果使用windows系统,应该下载预建的二进制版本。可以选择支持Unicode或不支持Unicode的版本,除非要用到Unicode,否则选择哪个版本区别不大。如果没有任何版本适合硬件或操作系统(或python版本),可以下载源代码发布版。为了编译可能还需要根据各种先决条件下载其他的源代码包。
在下载wxPython后,建议下载演示版本(demo,它必须独立安装),其中包含文档、示例程序和非常详细的演示分布。
2:创建示例的GUI应用程序
最简单的wxPython程序应该像下面这样:
import wx app = wx.app() app.MainLoop()
3:窗口和组件——窗口(window)也成为框架(Frame),是wx.Frame类的实例。创建并显示一个框架:
import wx app = wx.app() win = wx.Frame(None) win.Show() app.MainLoop()
4:事件处理——在GUI术语中,用户执行的动作(比如点击按钮)叫做事件(event)。你需要让程序注意这些事件并作出反应。可以将函数绑定到所涉及的事件可能发生的组件上达到这个效果。当事件发生时,函数会被调用。假设写了一个负责打开文件的函数,并将其命名为load,然后就可以像下面这样讲函数作为loadButton的事件处理函数:
loadButton.Bind(wx.EVT_BUTTON,load)