CSV
csv文件格式是一種通用的電子表格和數據庫導入導出格式
簡介
Python csv模塊封裝了常用的功能,使用的簡單例子如下:
寫入
# 寫入csv文件
import csv
csvfile = open('csv_test.csv', 'w',newline='')
# 如果不指定newline='',有時則每寫入一行將有一空行被寫入
writer = csv.writer(csvfile)
writer.writerow(['姓名', '年齡', '電話']) # 寫入一行用writerow
data = [
('al', '25', '1367890900'),
('eg', '18', '1367890800')
]
writer.writerows(data) # 多行用writerows
csvfile.close()
讀取
# 讀取csv文件
csv_reader = csv.reader(open('csv_test.csv', encoding='utf-8'))
for row in csv_reader:
print(row)
# ['姓名', '年齡', '電話']
# ['al', '25', '1367890900']
# ['eg', '18', '1367890800']
默認的情況下, 讀和寫使用逗號做分隔符(delimiter),用雙引號作為引用符(quotechar),當遇到特殊情況是,可以根據需要手動指定字符, 例如:
import csv
with open('/etc/passwd', 'r') as f:
reader = csv.reader(f, delimiter=':', quoting=csv.QUOTE_NONE)
for row in reader:
print(row)
['root', 'x', '0', '0', 'root', '/root', '/bin/bash']
['bin', 'x', '1', '1', 'bin', '/bin', '/sbin/nologin']
['daemon', 'x', '2', '2', 'daemon', '/sbin', '/sbin/nologin']
……
上述示例指定冒號作為分隔符,並且指定quote方式為不引用。這意味着讀的時候都認為內容是不被默認引用符(")包圍的。
quoting的可選項為: QUOTE_ALL, QUOTE_MINIMAL, QUOTE_NONNUMERIC, QUOTE_NONE.
有點需要注意的是,當用writer寫數據時, None 會被寫成空字符串,浮點類型會被調用 repr() 方法轉化成字符串。所以非字符串類型的數據會被 str() 成字符串存儲。
字典方式地讀寫
csv還提供了一種類似於字典方式的讀寫,方式如下:
格式如下:
headers = ['name', 'age']
datas = [{'name': 'Bob', 'age': 23},
{'name': 'Jerry', 'age': 44},
{'name': 'Tom', 'age': 15}
]
with open('example.csv', 'w', newline='') as f:
# 標頭在這里傳入,作為第一行數據
writer = csv.DictWriter(f, headers)
writer.writeheader()
for row in datas:
writer.writerow(row)
# 還可以寫入多行
writer.writerows(datas)
# 讀
import csv
with open('example.csv','r') as csvfile:
reader = csv.DictReader(csvfile)
for row in reader:
print(row['name'], row['age'])
# name,age
# Bob,23
# Jerry,44
# Tom,15
# Bob,23
# Jerry,44
# Tom,15
案例:使用csv格式展示磁盤空間
import re
import csv
import os
from prettytable import from_csv
import subprocess
# 寫入csv文件
import csv
def cmd_exec(cmd):
"""
執行shell命令
返回命令返回值和結果
:param cmd:
:return:
"""
p = subprocess.Popen(cmd,
shell=True,
stdin=subprocess.PIPE,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE)
stdout, stderr = p.communicate()
if p.returncode != 0:
return {'code':p.returncode, 'res':to_str(stderr)}
return {'code':p.returncode, 'res':to_str(stdout)}
def to_str(bytes_or_str):
"""
把byte類型轉換為str
:param bytes_or_str:
:return:
"""
if isinstance(bytes_or_str, bytes):
value = bytes_or_str.decode('utf-8')
else:
value = bytes_or_str
return value
f = open('disk.csv', 'w+', newline='', encoding='utf-8' )
fieldnames = ['Dir', 'Use%', 'Avail', 'Used', 'Size']
writer = csv.writer(f)
writer.writerow(fieldnames)
df_ret = cmd_exec('df -h| grep -E \([1-9]?[1-9]\%\)\|\(100\%\)')
if df_ret['code'] == 0:
if df_ret['res']:
for item in df_ret['res'].split('\n')[:-1]: # 截取回車
d = re.split(r'\s+', item) # 去除空格符
writer.writerow(d[-1:-6:-1])
f.flush() # 寫入到磁盤
# os.fsync() 方法強制將文件描述符為fd的文件寫入硬盤。在Unix, 將調用fsync()函數;在Windows, 調用 _commit()函數。
# 如果你准備操作一個Python文件對象f, 首先f.flush(),然后os.fsync(f.fileno()),
# 確保與f相關的所有內存都寫入了硬盤.在unix,Windows中有效。
os.fsync(f.fileno())
f.seek(0) # 把文件指針置於開頭
tb = from_csv(f)
### 設定左對齊
tb.align = 'l'
### 設定T_ID右對齊
tb.align["Use%"] = "r"
### 設定數字輸出格式
tb.float_format = "2.2"
### 設定邊框連接符為'*"
tb.junction_char = "*"
# ### 設定排序列
# tb.sortby = "Use%"
# ### 設定排序方式
# tb.reversesort = True
### 設定左側不填充空白字符
tb.left_padding_width = 0
print(tb) # 打印表格
*---------*-----*------*-----*-----*
|Dir |Use% |Avail |Used |Size |
*---------*-----*------*-----*-----*
|/ | 11% |82G |9.3G |96G |
|/dev/shm | 1% |931M |72K |931M |
|/boot | 9% |421M |39M |485M |
*---------*-----*------*-----*-----*
