Python學習目錄python
IO在計算機中指Input/Output,也就是輸入和輸出。因爲程序和運行時數據是在內存中駐留,由CPU這個超快的計算核心來執行,涉及到數據交換的地方,一般是磁盤、網絡等,就須要IO接口。npm
上代碼:編程
try:
//讀文件
f = open('/path/to/file', 'r')
print(f.read())
//寫文件
f = open('/Users/michael/test.txt', 'w')
f.write('Hello, world!')
finally:
if f:
//關閉文件
f.close()
複製代碼
等價於:json
//讀文件
with open('/path/to/file', 'r') as f:
print(f.read())
//寫文件
with open('/Users/michael/test.txt', 'w') as f:
f.write('Hello, world!')
複製代碼
一、讀模式打開文件vim
要以讀文件的模式打開一個文件對象,使用Python內置的open()
函數,傳入文件名和標示符:api
>>> f = open('/Users/michael/test.txt', 'r')
複製代碼
標示符'r'表示讀,這樣,咱們就成功地打開了一個文件。網絡
二、寫模式打開文件app
>>> f = open('/Users/michael/test.txt', 'w')
複製代碼
三、帶編碼方式打開文件(讀或者寫)ssh
默認讀寫文件的編碼方式是UTF-8,要讀取非UTF-8編碼的文本文件,須要給open()
函數傳入encoding
參數,例如,讀取GBK編碼的文件:編程語言
>>> f = open('/Users/michael/gbk.txt', 'r', encoding='gbk')
複製代碼
要讀取二進制文件,好比圖片、視頻等等,用'rb'
模式打開文件便可:
>>> f = open('/Users/michael/test.jpg', 'rb')
複製代碼
若是文件打開成功,接下來,調用read()
方法能夠一次讀取文件的所有內容,Python把內容讀到內存,用一個str
對象表示:
>>> f.read()
複製代碼
調用read()
會一次性讀取文件的所有內容,若是文件有10G,內存就爆了,因此,要保險起見,能夠反覆調用read(size)
方法,每次最多讀取size個字節的內容。另外,調用readline()
能夠每次讀取一行內容,調用readlines()
一次讀取全部內容並按行返回list
。所以,要根據須要決定怎麼調用。
若是文件很小,read()
一次性讀取最方便;若是不能肯定文件大小,反覆調用read(size)
比較保險;若是是配置文件,調用readlines()
最方便:
for line in f.readlines():
print(line.strip()) # 把末尾的'\n'刪掉
複製代碼
像open()
函數返回的這種有個read()
方法的對象,在Python中統稱爲file-like Object。除了file外,還能夠是內存的字節流,網絡流,自定義流等等。file-like Object不要求從特定類繼承,只要寫個read()
方法就行。
StringIO
就是在內存中建立的file-like Object,經常使用做臨時緩衝。
寫文件和讀文件是同樣的,惟一區別是調用open()
函數時,傳入標識符'w'
或者'wb'
表示寫文本文件或寫二進制文件:
f.write('Hello, world!')
複製代碼
最後一步是調用close()
方法關閉文件。文件使用完畢後必須關閉,由於文件對象會佔用操做系統的資源,而且操做系統同一時間能打開的文件數量也是有限的:
>>> f.close()
複製代碼
不少時候,數據讀寫不必定是文件,也能夠在內存中讀寫。
StringIO顧名思義就是在內存中讀寫str。
要把str寫入StringIO,咱們須要先建立一個StringIO,而後,像文件同樣寫入便可:
>>> from io import StringIO
>>> f = StringIO()
>>> f.write('hello')
5
>>> f.write(' ')
1
>>> f.write('world!')
6
>>> print(f.getvalue())
hello world!
複製代碼
getvalue()
方法用於得到寫入後的str。
要讀取StringIO,能夠用一個str初始化StringIO,而後,像讀文件同樣讀取:
>>> from io import StringIO
>>> f = StringIO('Hello!\nHi!\nGoodbye!')
>>> while True:
... s = f.readline()
... if s == '':
... break
... print(s.strip())
...
Hello!
Hi!
Goodbye!
複製代碼
StringIO操做的只能是str,若是要操做二進制數據,就須要使用BytesIO。
BytesIO實現了在內存中讀寫bytes,咱們建立一個BytesIO,而後寫入一些bytes:
>>> from io import BytesIO
>>> f = BytesIO()
>>> f.write('中文'.encode('utf-8'))
6
>>> print(f.getvalue())
b'\xe4\xb8\xad\xe6\x96\x87'
複製代碼
請注意,寫入的不是str,而是通過UTF-8編碼的bytes。
和StringIO相似,能夠用一個bytes初始化BytesIO,而後,像讀文件同樣讀取:
>>> from io import BytesIO
>>> f = BytesIO(b'\xe4\xb8\xad\xe6\x96\x87')
>>> f.read()
b'\xe4\xb8\xad\xe6\x96\x87'
複製代碼
若是咱們要操做文件、目錄,能夠在命令行下面輸入操做系統提供的各類命令來完成。好比dir
、cp
等命令。
若是要在Python程序中執行這些目錄和文件的操做怎麼辦?其實操做系統提供的命令只是簡單地調用了操做系統提供的接口函數,Python內置的os
模塊也能夠直接調用操做系統提供的接口函數。
操做文件和目錄的函數一部分放在os
模塊中,一部分放在os.path
模塊中。
看看如何利用Python的特性來過濾文件。好比咱們要列出當前目錄下的全部目錄,只須要一行代碼:
>>> [x for x in os.listdir('.') if os.path.isdir(x)]
['.lein', '.local', '.m2', '.npm', '.ssh', '.Trash', '.vim', 'Applications', 'Desktop', ...]
複製代碼
要列出全部的.py
文件,也只需一行代碼:
>>> [x for x in os.listdir('.') if os.path.isfile(x) and os.path.splitext(x)[1]=='.py']
['apis.py', 'config.py', 'models.py', 'pymonitor.py', 'test_db.py', 'urls.py', 'wsgiapp.py']
複製代碼
咱們把變量從內存中變成可存儲或傳輸的過程稱之爲序列化,在Python中叫pickling,在其餘語言中也被稱之爲serialization,marshalling,flattening等等,都是一個意思。
序列化以後,就能夠把序列化後的內容寫入磁盤,或者經過網絡傳輸到別的機器上。
反過來,把變量內容從序列化的對象從新讀到內存裏稱之爲反序列化,即unpickling。
Python提供了pickle
模塊來實現序列化。Pickle的問題和全部其餘編程語言特有的序列化問題同樣,就是它只能用於Python,而且可能不一樣版本的Python彼此都不兼容,所以,只能用Pickle保存那些不重要的數據,不能成功地反序列化也不要緊。
若是咱們要在不一樣的編程語言之間傳遞對象,就必須把對象序列化爲標準格式,好比XML,但更好的方法是序列化爲JSON,由於JSON表示出來就是一個字符串,能夠被全部語言讀取,也能夠方便地存儲到磁盤或者經過網絡傳輸。JSON不只是標準格式,而且比XML更快,並且能夠直接在Web頁面中讀取,很是方便。
Python內置的json
模塊提供了很是完善的Python對象到JSON格式的轉換。咱們先看看如何把Python對象變成一個JSON:
>>> import json
>>> d = dict(name='Bob', age=20, score=88)
>>> json.dumps(d)
'{"age": 20, "score": 88, "name": "Bob"}'
複製代碼
dumps()
方法返回一個str
,內容就是標準的JSON。相似的,dump()
方法能夠直接把JSON寫入一個file-like Object
。
要把JSON反序列化爲Python對象,用loads()
或者對應的load()
方法,前者把JSON的字符串反序列化,後者從file-like Object
中讀取字符串並反序列化:
>>> json_str = '{"age": 20, "score": 88, "name": "Bob"}'
>>> json.loads(json_str)
{'age': 20, 'score': 88, 'name': 'Bob'}
複製代碼
因爲JSON標準規定JSON編碼是UTF-8,因此咱們老是能正確地在Python的str
與JSON的字符串之間轉換。