Python 檔案讀寫
一.file物件(file-like Object)
在標準庫中,不需要安裝
1.file 物件使用 open 函式來建立:
f = open(/path/1.txt, mode='r')
2.open函式引數:
open(file, mode=‘r’, buffering=-1, encoding=None, errors=None, newline=None, closefd=True)
- file:必需,檔案路徑(相對或者絕對路徑);
- mode: 檔案開啟模式;
- buffering:可取值有0,1, >1三個,0代表buffer關閉(只適用於二進位制模式),1代表line buffer(只適用於文字模式),>1表示初始化的buffer大小;
- encoding:表示的是返回的資料採用何種編碼,一般採用utf8或者gbk;
- errors的取值一般有strict,ignore,當取strict的時候,字元編碼出現問題的時候,會報錯,當取ignore的時候,編碼出現問題,程式會忽略而過,繼續執行下面的程式。
- newline:可以取的值有None, \n, \r, ’’, ‘\r\n’ ,用於區分換行符,但是這個引數只對文字模式有效;
- closefd:取值與傳入的檔案引數有關,預設情況下為True,傳入的file引數為檔案的檔名,取值為False的時候,file只能是檔案描述符,什麼是檔案描述符,就是一個非負整數,在Unix核心的系統中,開啟一個檔案,便會返回一個檔案描述符。
3.常見mode模式:
- r或rt:預設模式,文字模式讀
- rb:二進位制檔案
- w或wt:文字模式寫,開啟前檔案儲存被清空
- wb:二進位制寫,檔案儲存同樣被清空
- a:追加模式,只能寫在檔案末尾
- a+:可讀寫模式,寫只能寫在檔案末尾
- w+:可讀寫,與a+的區別是要清空檔案內容
- r+:可讀寫,與a+的區別是可以寫到檔案任何位置
4.file物件函式:
- file.close():關閉檔案。關閉後文件不能再進行讀寫操作。
- file.next():返回檔案下一行。
- file.read([size]):從檔案讀取指定的位元組數,如果未給定或為負則讀取所有。
- file.readline([size]):讀取整行,包括 “\n” 字元。
- file.readlines([sizeint]):讀取所有行並返回列表,若給定sizeint>0,則是設定一次讀多少位元組,這是為了減輕讀取壓力。
- file.seek(offset[, whence]):設定檔案當前位置。
- file.tell():返回檔案當前位置。
- file.truncate([size]):擷取檔案,擷取的位元組通過size指定,預設為當前檔案位置。
- file.write(str):將字串寫入檔案,返回的是寫入的字元長度。
- file.writelines(sequence):向檔案寫入一個序列字串列表,如果需要換行則要自己加入每行的換行符。
5.with語句: 檔案讀寫完畢後必須呼叫f.close()的原因:
- 檔案使用完畢後必須關閉,因為檔案物件會佔用作業系統的資源,並且作業系統同一時間能開啟的檔案數量也是有限的;
- 寫檔案時,作業系統往往不會立刻把資料寫入磁碟,而是放到記憶體快取起來,空閒的時候再慢慢寫入。只有呼叫close()方法時,作業系統才保證把沒有寫入的資料全部寫入磁碟。忘記呼叫close()的後果是資料可能只寫了一部分到磁碟,剩下的丟失了。
可以使用 try … finally 來實現,但是每次都這麼寫實在太繁瑣:
try:
f = open('/path/to/file', 'r')
print(f.read())
finally:
if f:
f.close()
try:
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
finally:
if f:
f.close()
Python引入了with語句來自動幫我們呼叫close()方法:
with open('/path/to/file', 'r') as f:
print(f.read())
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
這和前面的try … finally是一樣的,但是程式碼更佳簡潔,並且不必呼叫f.close()方法。
二.CSV模組
在標準庫中,不需要安裝
1.reader函式:
reader(csvfile, dialect='excel', **fmtparams)
引數說明:
- csvfile:必須是支援迭代(Iterator)的物件,可以是檔案(file)物件或者列表(list)物件,如果是檔案物件,開啟時需要加"b"標誌引數。
- dialect:編碼風格,預設為excel的風格,也就是用逗號(,)分隔,dialect方式也支援自定義,通過呼叫register_dialect方法來註冊,下文會提到。
- fmtparam:格式化引數,用來覆蓋之前dialect物件指定的編碼風格。
函式:
- csvreader.__next__(): Return the next row of the reader’s iterable object as a list (if the object was returned from reader()) or a dict (if it is a DictReader instance), parsed according to the current dialect. Usually you should call this as next(reader).
屬性:
- csvreader.dialect: A read-only description of the dialect in use by the parser.
- csvreader.line_num: The number of lines read from the source iterator. This is not the same as the number of records returned, as records can span multiple lines.
2.writer函式:
writer(csvfile, dialect='excel', **fmtparams)
函式:
- csvwriter.writerow(row): Write the row parameter to the writer’s file object, formatted according to the current dialect.
- csvwriter.writerows(rows): Write all elements in rows (an iterable of row objects as described above) to the writer’s file object, formatted according to the current dialect.
屬性:
- csvwriter.dialect: A read-only description of the dialect in use by the writer.
3.register_dialect函式: 自定義dialect
register_dialect(name, [dialect, ]**fmtparams)
- name:你所自定義的dialect的名字,比如預設的是’excel’,你可以定義成’mydialect’。
- [dialect, ]**fmtparams:dialect格式引數,有delimiter(分隔符,預設的就是逗號)、quotechar、quoting等等,可以參考官方文件。
4.unregister_dialect函式: 登出自定義的dialect
unregister_dialect(name)
5.常用語句:
- 從檔案中獲取列標題:
import csv
filename = '1.csv'
with open(filename) as f:
reader = csv.reader(f)
header_row = next(reader)
for index, column_header in enumerate(header_row):
print(index, column_header)
- 從檔案中獲取某一列:
import csv
filename = '1.csv'
with open(filename) as f:
reader = csv.reader(f)
next(reader)
highs = []
for row in reader:
highs.append(row[4])
print(highs)
三.DOCX模組
不在標準庫中,需要安裝(通過命令列下載的docx安裝包未完全相容python3,需要另行下載):
在 https://www.lfd.uci.edu/~gohlke/pythonlibs/ 中找到python_docx-x.x.x-py2.py3-none-any.whl
下載到本地後安裝:pip install python_docx-x.x.x-py2.py3-none-any.whl
1.檔案讀取與寫入:
import docx
doc = docx.Document('1.docx')
# doc = docx.Document() 僅新建一個Document物件,不讀取檔案
doc.save('2.docx')
2.表格:
寫入表格
import docx
doc = docx.Document()
# 建一個4行3列的表
table = doc.add_table(rows=1, cols=3, style='Table Grid')
header_cells = table.rows[0].cells
header_cells[0].text = 'Name'
header_cells[1].text = 'Id'
header_cells[2].text = 'Desc'
data_lines = 3
for i in range(data_lines):
cells = table.add_row().cells
cells[0].text = "Name%d" %i
cells[1].text = "Id%d" %i
cells[2].text = "Desc%d" %i
# 建一個2行4列的表
rows = 2
cols = 4
table = doc.add_table(rows=rows, cols=cols)
val = 1
for i in range(rows):
cells = table.rows[i].cells
for j in range(cols):
cells[j].text = str(val * 10)
val += 1
doc.save('tmp.docx')
讀取表格
import docx
doc = docx.Document('tmp.docx')
for table in doc.tables: # 遍歷所有表格
print('----table------')
for row in table.rows: # 遍歷表格的所有行
# 方法一
for cell in row.cells:
print(cell.text + '\t', end='')
print()
# 方法二
row_str = '\t'.join([cell.text for cell in row.cells])
# ''.join()插入分隔符
print(row_str)
3.段落:
import docx
doc = docx.Document('1.docx')
content = '\n'.join([para.text for para in doc.paragraphs])
print(content)
4.綜合運用:
from docx import Document
from docx.shared import Inches
document = Document()
document.add_heading('Document Title', 0)
p = document.add_paragraph('A plain paragraph having some ')
p.add_run('bold').bold = True
p.add_run(' and some ')
p.add_run('italic.').italic = True
document.add_heading('Heading, level 1', level=1)
document.add_paragraph('Intense quote', style='Intense Quote')
document.add_paragraph(
'first item in unordered list', style='List Bullet'
)
document.add_paragraph(
'first item in ordered list', style='List Number'
)
document.add_picture('1.png', width=Inches(1.25))
records = (
(3, '101', 'Spam'),
(7, '422', 'Eggs'),
(4, '631', 'Spam, spam, eggs, and spam')
)
table = document.add_table(rows=1, cols=3)
hdr_cells = table.rows[0].cells
hdr_cells[0].text = 'Qty'
hdr_cells[1].text = 'Id'
hdr_cells[2].text = 'Desc'
for qty, id, desc in records:
row_cells = table.add_row().cells
row_cells[0].text = str(qty)
row_cells[1].text = id
row_cells[2].text = desc
document.add_page_break()
document.save('demo.docx')
效果