Python I/O與進程
I/O
with語句
with context_expression [as target(s)]:
with-body
context_expression
返回值遵從上下文管理協議,包含__enter__()
與__exit__()
方法,as語句的target(s)得到的是__enter__()
返回值,執行with-body
後會調用上下文管理器的__exit__()
方法,使用with語句,可以減輕某些代碼編寫負擔,比如文件讀寫。
讀文件
try:
f = open('/path/to/file', 'r', encoding='utf8', errors='ignore')
print(f.read(1024))
finally:
if f:
f.close()
# 使用with語句
with open('/path/to/file', 'r') as f:
print(f.read(1024))
open()方法打開文件模式,默認以utf8格式讀取,添加後綴’b’(rb、wb)表示以二進制方式讀取,mode有以下幾種:
mode | 描述 |
---|---|
r | 只讀 |
w | 只寫 |
a | 追加 |
r+ | 讀寫 |
StringIO和BytesIO
StringIO將string按照文件的方式讀取和寫入,BytesIO將bytes按照文件的的方式讀取和寫入。
OS
通過OS模塊,與操作系統信息交互,如創建、移動、列出文件等等。
序列化
通過內置模塊pickle,實現序列化與反序列化,使用json模塊完成JSON數據的序列化和反序列化。
import pickle
d = dict(name = 'sha', age = 26)
# 將序列化內容寫入文件
with open('dump', 'wb') as f:
pickle.dump(d, f)
# 從文件中讀取序列化內容
with open('dump', 'rb') as f:
d = pickle.load(f)
print(d) # {'name': 'sha', 'age': 26}
進程與線程
進程
Python調用一次進程fork()會有兩次返回,子進程永遠返回0,父進程中返回子進程ID。os.fork()
不支持windows,multiprocessing模塊是跨平臺版本的多進程模塊。
import os
pid = os.fork() # pid後的代碼會在兩個進程中分別執行,通過pid值不同判斷父子
if pid == 0:
print('exec in child process')
else:
print('exec in parent process')
# exec in parent process
# exec in child process
進程池
from multiprocessing import Pool
def say(x):
print(x)
if __name__ == '__main__':
p = Pool(4)
for i in range(5):
p.apply_async(say, args=(i,))
p.close()
p.join()
子進程
import subprocess
print('$ nslookup amsimple.com')
r = subprocess.call(['nslookup', 'amsimple.com'])
print('Exit code:', r)
進程間通信
進程間通信通過Queue與Pipes實現,父進程創建Queue傳遞給子進程。
線程
Python提供兩個模塊_thread與threading,前者是低級模塊後者是高級模塊,對_thread進行了封裝。
啓動一個線程就是把一個函數傳入並創建Thread實例,然後調用start()開始執行:
import threading
# 新線程執行的代碼:
def say():
print('%s say hello' % threading.current_thread().name)
t = threading.Thread(target=say, name = 'SayThread')
t.start()
t.join()
threading.current_thread()
返回但前運行線程的實例,主線程名MainTreed,子線程名在創建時指定。
通過threading.Lock()
獲取鎖,某些需要線程安全的操作,先通過acquire()獲取鎖,通過release()釋放鎖。
Python中的線程因爲GIL鎖,無法真正利用多核。
通過ThreadLocal實現線程級的全局變量,不同線程間相互不影響。
import threading
th_local = threading.local() # th_local會跟線程綁定,不同線程看到的是不同對象
分佈式進程
managers模塊依靠網絡通信,可以把多進程分佈到多臺機器上。
正則
通過’r’前綴定義正則字符串,通過re模塊做正則匹配等操作。
import re
s = r'^[a-zA-Z0-9_-]+@[a-zA-Z0-9_-]+(\.[a-zA-Z0-9_-]+)+$'
re.match(s, '[email protected]')