[Python]輸入與輸出

1. 讀取命令行選項

Python啓動時,命令行選項放置在列表sys.argv中。例如:

import sys
if len(sys.argv) != 3:
    sys.stderr.write("Usage: python %s inputfile outputfile\n" % sys.argv[0])
    raise SystemExit(1)
inputfile = sys.argv[1]
outputfile = sys.argv[2]

在該程序中,sys.argv[0]包含所執行腳本的名稱。對於更復雜的命令行處理,可以使用optparse模塊。例如:

imprt optparse
p = optparse.OptionParser()
# 選項接受一個參數
p.add_option("-o", action="store", dest="outfile")
p.add_option("--output", action="store", dest="outfile")
# 選項設置一個布爾值標誌
p.add_option("-d", action="store_true", dest="debug")
p.add_option("--debug", action="store_true", dest="debug")
# 設置選定選項的默認值
p.set_defaults(debug=False)
# 解析命令行
opts, args = p.parse_args()
# 檢索選項設置
outfile = opts.outfile
debugmode = opts.debug

以上例子中添加了兩類選項。第一個選項-o或--output具有一個必需參數。這是通過指定action='store'實現的。dest參數選擇將在解析後存儲參數值的屬性名稱。p.set_defaults()方法設置一個或多個選項的默認值。
使用p.parse_args()方法執行解析。該方法返回一個二元組(opts, args),其中opts是包含已解析選項值的對象,args是命令行上未解析爲選項的項目列表。選項值使用opts.dest檢索。
 

2. 環境變量

可以通過字典os.environ訪問環境變量,例如:

import os
path = os.environ["PATH"]
user = os.environ["USER"]
editor = os.environ["EDITOR"]

要修改環境變量,需要設置os.environ變量,例如:

os.environ["FOO"] = "BAR"

 

3. 文件和文件對象

內置函數open(name [, mode [, bufsize]])用於打開和創建文件對象,例如:

f = open("foo")
f = open("foo", "r")
f = open("foo", "w")

文件模式"r"表示讀取,"w"表示寫入,"a"表示附加。這些文件模式假定採用文本模式,可以隱式對換行字符"\n"執行轉換。如果正在處理二進制數據,可以將"b"附加到文件模式後面,如"rb"或"wb"。這將禁用換行符轉換。如果使用模式"U"或"rU"打開文件,將會提供通用的換行符支持,以方便閱讀。
通過提供"+"字符,比如"r+"或"w+",可以打開文件進行直接更新。打開文件進行更新時,可以同時執行輸入和輸出,只要所有輸出操作在任何後續輸入操作之前清除其數據即可。如果使用"w+"模式打開文件,其長度首先會被截斷爲0。
可選的bufsize參數控制文件的緩衝行爲,其中0表示沒有緩存,1表示進行了行緩衝,任何其他正值都表示將使用的近似緩衝區大小。
下表列表file對象支持的方法:

方法 描述
f.read([n]) 最多讀取n個字節
f.readline([n]) 讀取單行輸入的最多n個字符。
f.readlines([size]) 讀取所有行並返回一個列表。
f.wirte(s) 寫入字符串s
f.writelines(lines) 寫入序列lines中的所有字符串
f.close() 關閉文件
f.tell() 返回當前文件指針
f.seek(offset [, whence]) 查找新文件位置
f.isatty() 如果f是一個交互式終端,則返回1
f.flush() 清除輸出緩衝區
f.truncate([size]) 將文件截斷爲最多size字節
f.fileno() 返回一個整數文件描述符
f.next() 返回下一行或引發StopIteration

read()方法以字符串形式返回整個文件,除非指定了最大字符數。readline()方法返回下一行輸入,包括最後的換行符。readlines()方法以字符串列表的形式返回所有輸入行。readlines()方法接受一個Size參數,指定在停止讀取之前要讀取的近似字符數。
write()方法將一個字符串寫入到文件。writelines()方法將一個字符串列表寫入到文件中。write()和writelines()不會將換行字符添加到輸出中,所有生成的所有輸出都應該已經包含所有必要的格式。
在內部,每個文件對象都有一個文件指針,用於存儲下次讀取或寫入操作所需的字節偏移位置。tell()方法以長整型返回文件指針的當前值。seek()方法根據給定的offset和whence中的位置規則隨機訪問文件的各個部分。
fileno()方法返回文件的整數文件描述符,有時用在某些庫模塊中的低級I/O操作中。
文件對象還擁有一些只讀數據屬性,例如:

屬性 描述
f.closed 布爾值,表示文件狀態。已打開則爲False,已關閉則爲True
f.mode 文件的I/O模式
f.name 如果使用open()創建文件,則爲文件名稱。否則將是一個表示文件來源的字符串
f.softspace 布爾值,指示在使用print()語句時,是否應該在一個值之前打印空格字符。
f.newlines 在通用換行符模式下打開一個文件時,該屬性包含可在文件中實際找到的換行符表示。
f.encoding 一個字符串,指示文件編碼。

 

4. 標準輸入、輸出和錯誤

解釋器提供了3種標準文件對象,分別爲標準輸入、標準輸出和標準錯誤,它們在sys模塊中分別以sys.stdin、sys.stdout和sys.stderr的形式提供。stdin是與提供給解釋器的輸入字符流相對應的文件對象。stdout是一個文件對象,接收由print生成的輸出。stderr是接收錯誤消息的文件。
例如,以下代碼寫入標準輸出並從標準輸入中讀取一行輸入:

import sys
sys.stdout.write("Enter your name:")
name = sys.stdin.readline()

另外,內置函數input(prompt)也可以從stdin讀取一行文本,並可以打印一個提示符。鍵盤中斷(通常由Ctrl+C生成)會生成KeyboardInterrupt異常,可使用異常處理程序捕獲該異常。
 

5. print()函數

要打印一系列以空格分隔的值,只需將這些值提供給print(),例如:

print("The values are", x, y, z)

要禁止或更改行終止,可以使用end=ending關鍵字參數,例如:

print("The values are", x, y, z, end='') # 禁止換行符

要將輸出重定向到一個文件,可以使用file=outfile關鍵字參數,例如:

print("The values are", x, y, z, file=f)

要更改項目之間的分隔字符,可以使用sep=sepchr關鍵字參數,例如:

print("The values are", x, y, z, spe=',')

 

6. 文本輸出中的變量插入

通過格式化I/O與三對帶引號的字符串來將變量插入字符串中,例如:

# 斜槓可以防止第一行顯示爲空行
form = """\
Dear %(name)s,
Please send back my %(item)s or pay me $%(amount)0.2f.
"""
print form % {'name': 'Mr.Bush', 'item': 'blender', 'amount': 50.00}

format()方法可以使以上代碼更簡潔,例如:

form = """\
Dear {name}s,
Please send back my {item}s or pay me $%{amount:0.2f}.
"""
print form.format {name='Mr.Bush', item='blender', amount=50.00}

 

7. Unicode處理

如果有一個原始字節字符串s,其中包含已編碼的Unicode字符串表示,那麼可以使用s.decode([encoding [, errors]])方法將其轉換爲合適的Unicode字符串。要將Unicode字符串u轉換爲已編碼的字節字符串,可以使用字符串方法u.encoding([encoding [, errors]])。這兩種轉換字符串都需要使用一個特殊編碼名稱,指定如何在Unicode字符值與字節字符串中的一個8位字符序列上建立起映射關係。以下編碼是最常用的:

編碼 描述
ascii 7位ASCII碼
latin-1或iso-8859-1 ISO 8859-1 Latin-1
cp1252 Windows 1252編碼
utf-8 8位變長編碼
utf-16 16位變長編碼
utf-16-le UTF-16,小尾編碼
utf-16-be UTF-16,大尾編碼
unicode-escape 與Unicode字面量u"string"相同的格式
raw-unicode-escape 與Unicode字面量ur"string"相同的格式

默認編碼在site模塊中設置,可以使用sys.getdefaultencoding()查詢。在很多情況下,默認編碼是ascii,utf-8也是一種非常常見的設置。轉換字符串時,如果遇到無法轉換的字符,可能會引發UnicodeError異常。encode()和decode()方法的errors參數決定了如何處理編碼錯誤。可用參數如下:

參數 描述
strict 遇到編碼和解碼錯誤時,引發UnicodeError異常
ignore 忽略無效字符
replace 將無效字符替換爲一個替換字符
backslashreplace 將無效字符替換爲Python字符轉義序列
xmlcharrefreplace 將無效字符替換爲XML字符引用

處理Unicode字符串時,無法將原始Unicode數據直接寫入文件。因爲Unicode字符在內部表示爲多字節整數。Unicode字符串的外部表示總是根據具體的編碼規則進行,該編碼規則應該明確定義如何將Unicode字符表示爲字節序列。內置的codecs模塊包含一組函數,用於根據各種不同的數據編碼方案,在字節數據與Unicode字符串之間來回切換。
處理Unicode文件最直接方式是用codecs.open(filename [, mode [, encoding [, errors]]])函數,例如:

f = codecs.open('foo.txt', 'r', 'utf-8', 'strict')
g = codecs.open('bar.txt', 'w', 'utf-8')

這兩個函數創建了一個文件對象,用於讀取或寫入Unicode字符串。如果已經擁有一個文件對象,可以使用codecs.EncodedFile(file, inputenc [, outputenc [, errors]])函數爲該對象添加一個編碼包裝器,例如:

f = open("foo.txt", "rb")
...
fenc = codecs.EncodeFile(f, 'utf-8')

 

8. 對象持久性

有時會需要將對象內容保存到一個文件或從中進行還原。執行該任務的一種方法是編寫兩個函數,以一種特殊格式在文件中讀取和寫入數據。另一種方法是用pickle和shelve模塊。
pickle模塊將對象序列化爲一個字節流,這個字節流可以寫入到文件並在以後進行還原。例如:

import pickle
obj = SomeObject()
f = open(filename, 'wb')
pickle.dump(obj, f) # 將對象保存到f上
f.close()

要還原對象,可以使用以下代碼:

import pickle
f = open(filename, 'rb')
obj = pickle.load(f) # 還原對象
f.close()

可以依次發生一系列dump()操作來保存對象序列。要還原這些對象,只需使用一個類似的load()操作序列。shelve模塊類似於pickle,但它將對象保存在一個類似字典的數據庫中。例如:

import shelve
obj = SomeObject()
db = shelve.open("filename")
db['key'] = obj
...
obj = db['key']
db.close()

儘管由shelve創建的對象類似於一個字典,但它具有一些限制。首先,鍵必須是字符串。其次,shelve中存儲的值必須與pickle兼容。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章