用Python处理文件的实用姿势
這是“Python1024-自動(dòng)化辦公”的第一篇。
在Python1024的基礎(chǔ)篇中,我們已經(jīng)介紹過(guò)文件管理和文本文件的讀寫(xiě):
《編程的第一個(gè)應(yīng)用,往往都從文件讀寫(xiě)開(kāi)始》
在路徑處理方面,Python3.6版本后,建議采用pathlib,它采用面向?qū)ο蠓庋b接口,使用起來(lái)比os.path更人性化。
在學(xué)習(xí)后續(xù)章節(jié)前,有必要先介紹幾個(gè)基本的概念,方便后續(xù)的理解。
1、常見(jiàn)文件格式
文本文件其實(shí)是一種特殊的二進(jìn)制文件,它約定了以字符格式的讀取方式,字符符合ASCII或UNICODE等編碼標(biāo)準(zhǔn)。因?yàn)槲谋疚募ㄓ谩⑻厥?#xff08;字符形式)了,我們把它單獨(dú)列出對(duì)待。
其他二進(jìn)制文件則隨應(yīng)用的不同,有各式各樣的讀寫(xiě)規(guī)則。比如:
- PDF(Portable Document Format)文件,定義了一種獨(dú)立于應(yīng)用程序、硬件、操作系統(tǒng)的方式呈現(xiàn)文檔的文件格式。它內(nèi)部包含了大量類型的子元素,通過(guò)索引的方式嵌入在不同的位置。只有符合其規(guī)范的軟件,才能讀取,甚至修改PDF文件。PDF文件格式標(biāo)準(zhǔn)由Adobe定義:參考官網(wǎng)。
- 微軟2007版本之后的Office文件,比如docx、pptx、xlsx,屬于OpenXML文件格式。它是由微軟開(kāi)發(fā)的基于XML和ZIP壓縮技術(shù)的文件規(guī)范,并于2008年正式成為國(guó)際標(biāo)準(zhǔn)。可以用解壓縮軟件打開(kāi)這類文件,就能看到其內(nèi)部結(jié)構(gòu)。目前除了微軟Office軟件,我們也可以通過(guò)金山WPS、OpenOffice等軟件打開(kāi)其文檔。
- 圖像文件的格式非常多,根據(jù)壓縮算法不同,會(huì)設(shè)計(jì)不同的文件格式,比如:JPEG、TIFF、RAW、BMP、GIF、PNG。歸根到底,圖像代表的是色彩數(shù)據(jù),是整塊的內(nèi)容,而描述其數(shù)據(jù)結(jié)構(gòu)的,是文件頭部信息。
- 音頻文件,保存的是聲音信號(hào)的數(shù)字化,和圖像一樣,文件不同主要源于壓縮算法的不同。我們常見(jiàn)的音頻文件格式如:MP3、WAV、AAC、FLAC等,聲音信號(hào)被數(shù)字化后保存在數(shù)據(jù)塊中,同時(shí)由文件頭描述數(shù)據(jù)塊。關(guān)鍵信息如采樣率、比特率、聲道數(shù)。采樣率是時(shí)間相關(guān)的概念,即每秒收集多少次聲音樣本信息。
- 視頻文件,保存的是圖像和音頻的合集,即視頻文件可以拆分為視頻和音頻,其中視頻是圖像的合集,每秒鐘有多少?gòu)垐D像,就是它的FPS幀率,幀率決定了視頻的流暢度。此外,每張圖像的分辨率多大,決定了它的清晰度,比如我們常說(shuō)的720P代表1280×720的分辨率,1080P就是1920×1080的分辨率,即代表用1920×1080個(gè)像素點(diǎn)來(lái)表達(dá)一張圖片信息。所以,視頻文件尤其大,根據(jù)壓縮算法的不同,常見(jiàn)的文件格式如:MP4、MOV、FLV、WMV、WEBM等。
當(dāng)然,除了上面這些文件格式外,我們還可以定義自己的格式,只要定義的格式,能被對(duì)應(yīng)軟件支持打開(kāi)和寫(xiě)入即可。換句話說(shuō),如果你定義的文件格式,沒(méi)人寫(xiě)出軟件去支持,那就沒(méi)辦法應(yīng)用。或者,你自己寫(xiě)了軟件,但大部分人都不知道,或不想用,那它也就喪失了應(yīng)用價(jià)值。在軟件行業(yè)向互聯(lián)網(wǎng)演進(jìn)過(guò)程中,淘汰了大量的軟件,才誕生出目前相對(duì)穩(wěn)定的互聯(lián)網(wǎng)基礎(chǔ)設(shè)施。
Youtube上有人做了一個(gè)視頻,呈現(xiàn)了90年代到2020年間最受歡迎瀏覽器的更替:視頻地址。
2、文本文件也有分類
文本文件,本質(zhì)上是用于存儲(chǔ)字符的文件。
所有那些以字符保存的文件格式,其實(shí)都是文本文件,只不過(guò)文本內(nèi)容還有額外特定含義。
常見(jiàn)的比如:CSV、HTML、XML、JSON、JS、CSS,還有各種語(yǔ)言的代碼。
2.1 CSV文件
CSV文件常用于保存數(shù)據(jù)表格,比如:
姓名, 電話, 地址 張三, 18900000001, 上海 李四, 13800000002, 廣州這就是一個(gè)典型的CSV文件,我們可以用文本編輯器打開(kāi)它,也可以用Excel等軟件打開(kāi)它。如果用Excel軟件打開(kāi)它,Excel會(huì)把英文逗號(hào)作為分隔符號(hào),提取單元格內(nèi)容,我們看到的就是一張表格。
Python同樣也支持這類文件的讀寫(xiě),通過(guò)csv模塊:
這樣就能讀出CSV文件中的數(shù)據(jù):
姓名: 張三 電話: 18900000001 地址: 上海 姓名: 李四 電話: 13800000002 地址: 廣州2.2 XML文件
XML(eXtensible Markup Language)是為了結(jié)構(gòu)化存儲(chǔ)和傳輸數(shù)據(jù)而生,是一種標(biāo)記語(yǔ)言。
<?xml version="1.0" encoding="UTF-8"?> <mail><to>World</to><from>程一初</from><title>Hello World</title><body>Welcome to Python1024!</body> </mail>我們可以自定義標(biāo)記,一種定義就是一種數(shù)據(jù)格式。在Python中,有三種處理數(shù)據(jù)的方式:
- DOM(Document Object Model):文檔對(duì)象模型,是W3C組織推薦的標(biāo)準(zhǔn)編程接口。它把XML文件映射到內(nèi)存中,以“樹(shù)”的數(shù)據(jù)結(jié)構(gòu)來(lái)操作數(shù)據(jù)。
- SAX(simple API for XML):事件驅(qū)動(dòng)模型,雖然不是標(biāo)準(zhǔn),但應(yīng)用廣泛。它逐行掃描文檔,邊掃邊解析,這樣就不用一下子全裝載到內(nèi)存了。
- ElementTree:性能介乎于DOM和SAX之間,使用門(mén)檻低。
以ElementTree為例:
import pathlib import xml.etree.ElementTree as ETpath = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/001basic') xml_path = path.joinpath('hello.xml') tree = ET.parse(xml_path) root = tree.getroot() # 根節(jié)點(diǎn) print('root_tag:', root.tag) # 根標(biāo)簽:mail for elem in root:print(f'{elem.tag}: {elem.text}')此外,HTML是XML的一個(gè)子集,即HTML是一種特殊的XML,它定義了一整套標(biāo)簽規(guī)范,比如文字、超鏈接、表單等,按照這套規(guī)范來(lái)呈現(xiàn)HTML的應(yīng)用就是瀏覽器了。當(dāng)然,瀏覽器除了支持HTML,還需要支持JS腳本、CSS樣式文件等其他規(guī)范。
2.3 JSON文件
相比XML文件格式,JSON文件格式更精簡(jiǎn)。同樣的信息可以用更少的字符表示:
{"mail": {"to": "World","from": "程一初","title": "Hello World","body": "Welcome to Python1024!"} }少了對(duì)稱標(biāo)記以及<>符號(hào),JSON需要占用更少標(biāo)記數(shù)據(jù),所以它更常被用于互聯(lián)網(wǎng)應(yīng)用的數(shù)據(jù)傳輸。Python也內(nèi)置了處理模塊json:
import pathlib import jsonpath = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/001basic') json_path = path.joinpath('hello.json') with open(json_path, 'r') as f:data = json.loads(f.read()) print(f'root_tag: {list(data.keys())[0]}') for k, v in data['mail'].items():print(f'{k}: {v}')2.4 代碼文件
代碼文件,比如Python代碼文件,也是一種文本文件。所以,有一些靜態(tài)代碼檢測(cè)工具,如pylint、pep8、flake8等,可以讀取代碼文件后檢查編寫(xiě)質(zhì)量。甚至,你可以編寫(xiě)程序自動(dòng)生成代碼,在自動(dòng)化測(cè)試中用的比較多。
代碼文件的讀取和其他文本文件一樣,都可以用open()函數(shù)打開(kāi),但是要解析代碼文件,就必須用“語(yǔ)法樹(shù)”來(lái)解析,它也提供了對(duì)應(yīng)的ast模塊。比如我們寫(xiě)一個(gè)簡(jiǎn)單的Python代碼文件,包含一個(gè)注釋塊,以及一行代碼:
然后用語(yǔ)法樹(shù)解析它:
import pathlib import astpath = list(pathlib.Path.cwd().parents)[1].joinpath('data/automate/001basic') py_path = path.joinpath('hello.py') with open(py_path, 'r') as f:node = ast.parse(f.read()) # 獲取文檔注釋 print(ast.get_docstring(node))class MyVisitor(ast.NodeVisitor):# 定義一個(gè)遍歷代碼節(jié)點(diǎn)的類# 按需重定義generic_visit函數(shù)def generic_visit(self, node):print(node)super(MyVisitor, self).generic_visit(node) v = MyVisitor() v.visit(node)會(huì)得到這樣的結(jié)果:
Author: 程一初 <_ast.Module object at 0x118e4e890> <_ast.Expr object at 0x118ce1b50> <_ast.Str object at 0x118ce1f90> <_ast.Expr object at 0x118ce1d90> <_ast.Call object at 0x118ce1ad0> <_ast.Name object at 0x118ce1b10> <_ast.Load object at 0x103ed39d0> <_ast.Str object at 0x118eb3ed0>第一行為注釋文檔,剩下8行為ast內(nèi)部對(duì)象,包括模塊、表達(dá)式、字符串、函數(shù)名、調(diào)用等。這里只是舉個(gè)例子,說(shuō)明代碼文件也是一種特殊的文本文件。平時(shí)應(yīng)用中,我們幾乎不會(huì)這么去讀寫(xiě)代碼文件,而是直接用Python解釋器來(lái)執(zhí)行代碼。
總結(jié)
了解什么是文件,就能明白每個(gè)文件都有自己的規(guī)范,想要處理某類文件,就得先找到符合規(guī)范的應(yīng)用,或者模塊。找到模塊后,就可以通過(guò)結(jié)構(gòu)化的代碼來(lái)批量處理了。
常見(jiàn)的自動(dòng)化處理無(wú)非就這幾種:
- 批量文件處理,比如某個(gè)文件夾下的所有文件統(tǒng)一重命名;
- 根據(jù)提前設(shè)定的規(guī)則,自動(dòng)分類處理文件,比如按文件后綴調(diào)用不同程序處理;
- 組成流水線:把重復(fù)的工作提煉出標(biāo)準(zhǔn),把每一步程序化后再組裝起來(lái)。
Python的魅力,就是能把所有重復(fù)的工作,按模塊組織起來(lái),形成流水線,一個(gè)人發(fā)揮N個(gè)人的效率。
更多內(nèi)容請(qǐng)關(guān)注公眾號(hào):只差一個(gè)程序員了。
建個(gè)學(xué)習(xí)群,有興趣可以添加交流,前100名免費(fèi)。
總結(jié)
以上是生活随笔為你收集整理的用Python处理文件的实用姿势的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 移动布局+百分比布局+em+rem+动态
- 下一篇: websocket python爬虫_p