天天看點

python之檔案和素材

11.1 打開檔案

open函數

open(name[,mode[,buffering]])

>>>f = open(r'C:\text\somefile.txt')

11.1.1 檔案模式

open函數中模式參數的常用值

'r' 讀模式   

'w' 寫模式

'a' 追加模式

'b' 二進制模式

'+' 讀/寫模式

通過在模式參數中使用U參數能夠在打開檔案時使用通用的換行符支援模式,在這種模式下,所有的換行符/字元串(\r\n,\r或者是\n)都被轉換成\n,而不用考慮運作的平台。

11.1.2 緩沖

open函數的第三個參數控制者檔案的緩沖。如果參數是0或者False,I/O無緩沖的;如果是1或者True,就是有緩沖,大于1的數字代表緩沖區的大小,-1代表使用預設的緩沖區大小

11.2 基本檔案方法

三種标準的流

資料輸入得标準源是sys.stdin。

要列印的文本儲存在sys.stdout内。

錯誤資訊被寫入sys.stderr.

11.2.1 讀和寫

檔案最重要的能力是提供或者接受資料。如果一個名為f的類檔案對象,那麼就可以用f.write方法和f.read方法寫入和讀取資料。

每次調用f.write(string)時,所提供的參數string會被追加到檔案中已存在部分的後面。

>>>f = open('somefile.txt','w')

>>>f.write('Hello, ')

>>>f.write('world!')

>>>f.close()

在完成了對一個檔案的操作時,調用close。

例子:接上例:

>>>f = open('somefile.txt','r')

>>>f.read(4)

'Hello'

>>>f.read()

'o.World!'

首先指定了我要讀取的字元數“4”,然後讀取了剩下的檔案。注意,在調用open時可以省略模式說明,因為'r'是預設的。

11.2.2 管式輸出

$cat somefile.txt | python somescript.py | sort

somescript.py會從它的sys.stdin中讀取資料(cat somefile.txt寫入的),并把結果寫入它的sys.stdout中。

統計sys.stdin中單詞數的簡單腳本

#somescript.py

import sys

text = sys.stdin.read()

words = text.split()

wordcount = len(words)

print 'Wordcount:',wordcount

可以用類檔案對象seek和tell來直接通路感興趣的部分(這種做法稱為 随機通路)

seek(offset[,whence]):這個方法把目前位置移到由offest定義的位置。whence.offset是一個位元組數,whence預設為0,也就是說偏移量是從檔案開頭開始計算的。whence可能被設定為1或者2

>>>f = open(r'c:\text\somefile.txt','w')

>>>f.write('01234567890123456789')

>>>f.seek(5)

>>>f.write('Hello,world!')

>>>f = open(r'c:\text\somefile.txt')

'01234Hello,world!89'

tell方法傳回目前檔案的位置如下:

>>>f.read(3)

'012'

>>>f.read(2)

'34'

>>>f.tell()

5L

11.2.3 讀寫行

逐個字元讀取檔案也是沒問題的,進行逐行的讀取也可以。還可以使用file.readline讀取單獨的一行。不使用任何參數或者使用一個非負的整數作為readline可以讀取的字元的最大值。是以,如果someFile.readline()傳回‘Hello,World!\n’,someFile.readline(5)傳回‘Hello’。readlines方法可以讀取一個檔案中的所有行并将其作為清單傳回。

writelines方法和readlines相反:傳給它的一個字元串的清單,它會把所有的字元串寫入檔案。注意,程式不會增加新行,需要自己添加。沒有writeline方法,因為能使用write。

11.2.3 關閉檔案

如果想確定檔案被關閉了,那麼應該使用try/finally語句,并且在finally子句中調用close方法。

#Open your file here

try:

#Write data to your file

finally:

file.close()

事實上,有專門為這種情況設計的語句,with語句:

with open("somefile.txt") as somefile:

do_something(somefile)

with語句可以打開檔案并且将其指派到變量上。之後就可以将資料寫入語句體中的檔案。檔案在語句結束後會被自動關閉,即使是由于異常引起的結束也是如此。

在python 2.5 中,with語句隻有在導入如下的子產品後才可以用:

from __future__ import with_statement

直到關閉檔案才會寫入檔案。如果想繼續使用檔案,又想将磁盤上的檔案進行更新,以反映這些修改,那麼需要調用檔案對象的flush方法。

上下文管理器

with語句實際上是很通用的結構,允許使用所謂的上下文管理器。上下文管理器是一種支援__enter__ 和__exit__ 方法的對象。

__enter__方法不帶參數,它在進入with語句塊的時候被調用,傳回值綁定到在as關鍵字之後的變量。

__exit__方法帶有3個參數:異常類型、異常對象和異常回溯。在離開方法時這個函數被調用。如果__exit__傳回false,那麼所有的異常都不會被處理。它們的__enter__方法傳回檔案對象本身,__exit__方法關閉檔案。

11.2.5 使用基本檔案方法

一個簡單文本檔案

Welcome to this file

There is nothing here except

This stupid haiku

首先是read(n):

>>>f.read(7)

'Welcome'

'to'

然後是read():

>>>print f.read()

接着是readline():

>>>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

以及readlines():

>>import pprint

>>>pprint.pprint(opne(r'c:\text\somefile.txt').readlines())

['Welcome to this file\n'

'There is nothing here except\n'

'This stupid haiku']

注意,本例中我所使用的是檔案對象自動關閉的方式。

下面是寫檔案,首先是write(string):

>>>f.write('this\nis no\nhaiku')

運作後:

this

is no

haiku

最後是writelines(list):

>>>lines = f.readlines()

>>>line[1] = "isn't a\n"

>>>f.writelines(lines)

isn't a

11.3.1 按位元組處理

最常見的對檔案内容進行疊代的方法是while循環中使用read方法。例如,對每個字元進行循環。

用read方法對每個字元進行循環

f = open(filename)

char = f.read(1)

while char:

process(char)

f.close()

這個程式可以使用是因為當到達檔案的末尾時,read方法傳回一個空的字元串,但在那之前傳回的字元串包含一個字元,如果char是真,則表示還沒有到檔案末尾。

可以看到,指派語句char = f.read(1)被重複地使用,代碼重複通常被認為是一件壞事。

用不同的方式寫循環

while True:

if not char:break

11.3.2 按行操作

當處理文本檔案時,經常會對檔案的行進行疊代而不是處理單個字元。處理行使用的方法和處理字元一樣,即使用readline方法:

在while循環中使用readline

f = opne(filename)

while True;

line = f.readline()

if not line: break

process(line)

11.3.3 讀取所有内容

如果檔案不是很大,那麼可以使用不帶參數的read方法一次讀取整個檔案,或者使用readlines方法。

用read疊代每個字元

for char in f.read()

用readlines疊代行

for line in f.readlines():

11.3.4使用fileinput實作懶惰行疊代

在需要對一個非常大的檔案進行疊代行的操作時,readlines會占用太多的記憶體。這個時候可以使用while循環和readline方法來替代。當然,在python中如果能使用for循環,那麼它就是首選。本例恰好可以使用for循環可以使用一個名為懶惰行疊代的方法:說它懶惰是因為它隻是讀取實際需要的檔案部分。

用fileinput來對行進行疊代

import fileinput

for line in fileinput.input(filename):

11.3.5 檔案疊代器

疊代檔案

for line in f:

對檔案進行疊代而不使用變量存儲檔案對象

for line in open(filename)

注意sys.stdin是可疊代的,就像其他的檔案對象。是以如果想要疊代标準輸入中的所有行,可以按如下形式使用sys.stdin.

for line in sys.stdin:

可以對檔案疊代器執行和普通疊代器相同的操作。比如将它們轉換為字元串清單(使用list(open(filename)) ),這樣所達到的效果和使用readlines一樣。

>>>f.write('First line\n')

>>>f.write('Second line\n')

>>>f.write('Third line\n')

>>>lines = list(open('somefile.txt'))

>>>lines

['First line\n','Second line\n','Third line\n']

>>>first,second,third = open('somefile.txt')

>>>first

'First line\n'

>>>second

'Second line\n'

>>>third

'Third line\n'

在這個例子中,有幾點重要的:

1.使用print來向檔案内寫入内容,,這會在提供的字元串後面增加新的行

2.使用序列來對一個打開的檔案進行解包操作,把每行都放入一個單獨的變量中(這麼做是很有實用性的,因為一般不知道檔案中有多少行,但它示範了檔案對象的“疊代性”)

3.在寫檔案後關閉了檔案,是為了確定資料被更新到硬碟。

      本文轉自潘闊 51CTO部落格,原文連結:http://blog.51cto.com/pankuo/1661445,如需轉載請自行聯系原作者