一.內容框架:
二.概念:
IO在計算機中指的是Input/Output,也就是輸入輸出。
Stream(流)是一種重要的概念,分爲輸入流(Input Stream)和輸出流(Output Stream)。可以理解爲一個水管,數據相當於水管中的水只能單向流動。
打開文件是讀寫文件最常見的IO操作,爲了方便IO操作,文件讀寫之前需要打開文件,確定文件的讀寫模式。
文件模式是open函數中的mode參數,通過改變mode參數可以實現對文件的不同操作。
文件緩衝區是open函數中第三個參數buffering控制着文件的緩衝。
文件讀取主要分爲按字節讀取和按行進行讀取,經常用到的方法有read(),readlines(),close()。
文件寫入唯一的區別是在調用open方法時,傳入標識‘w’或者‘wb’標識寫入文本文件或者寫入二進制文件。
序列化是把內存中數據變成可存儲和可傳輸的過程。
反序列化是把變量內容從序列化對象重新讀取到內存中。
進程池可以提供指定數量的進程供用戶調用,默認大小事CPU的核數。
線程同步是多個線程共同對某個數據修改,則可能出現不可預料的結果,爲了保證數據的正確性,需要多個線程進行同步。
全局解釋器鎖(GIL):解釋執行Python代碼時,會產生互斥鎖來限制線程對共享資源的訪問,知道解釋器遇到I/O操作或者操作次數達到一定數目時纔會釋放GIL。
協程又稱爲微線程,纖程,是一種用戶級的輕量級線程。協程擁有自己的寄存器上下文和棧。協程調度切換時,將寄存器上下文和棧保存到其他地方,在切回來的時候,恢復先前保存的寄存器上下文和棧。
分佈式進程是將Process進程分佈到多臺機器上,充分利用多臺機器的性能完成複雜的任務。
本地隊列的網絡化是將分佈式進程進行封裝的過程。
連接到指定服務器進程的通信端口進行通信,所以網絡通信也可以看做兩個進程間的通信。
TCP編程:網絡編程一般包括兩部分,服務端和客戶端。TCP是一種面向連接的通信方式,主動發起連接的叫客戶端,被動響應連接的叫服務端。
UDP編程:只需要知道對方的IP地址和端口號,就可以直接發數據包,但是不關心是否能到達目的端。
三.方法
1.文件操作
文件打開 |
open() |
文件寫入 |
Write() |
文件讀取 |
read() |
文件讀取/行讀取 |
readlines() |
文件關閉 |
close() |
1.2文件模式
值 |
功能描述 |
‘r’ |
讀模式 |
‘w’ |
寫模式 |
‘a’ |
追加模式 |
‘b’ |
二進制模式 |
‘+’ |
讀/寫模式 |
1.3文件緩衝區
參數 |
|
0 |
I/O操作是無緩衝的,直接寫到硬盤上。 |
1 |
I/O操作是有緩衝的,數據先寫到內存裏,只有使用flush和close函數纔會將數據更新到硬盤上。 |
大於1 |
大於1表示緩衝區的大小。 |
-1 |
代表使用默認緩衝區的大小。 |
1.4操作文件目錄
os.getcwd() |
獲得當前Ptython腳本工作的目錄路徑 |
os.Listdir() |
返回指定目錄下的所有文件和目錄名 |
os.remove(filepath) |
刪除一個文件 |
os.removedirs() |
刪除多個空目錄 |
os.path.isfiles(filepath) |
檢驗給出的路徑是否是一個文件 |
os.path.isdir(filepath) |
檢驗給出的路徑是否是一個目錄 |
os.path.isabs() |
判斷是否是絕對路徑 |
os.path.exists() |
檢驗路徑是否真的存在 |
os.path.split() |
分離一個路徑的目錄名和文件名 |
os.path.splitext() |
分離擴展名 |
os.path.dirname(filepath) |
獲取路徑名 |
os.path.basename(filepath) |
獲取文件名 |
os.getnv()或os.putnv() |
設置環境變量 |
os.linesep |
給出平臺使用的終止符 |
os.name |
指示你正在使用的平臺 |
os.rename() |
重命名文件或者目錄 |
os.makedirs() |
創建多級目錄 |
os.mkdir() |
創建多個目錄 |
os.stat() |
獲取文件屬性 |
os.chmod() |
修改文件權限與時間戳 |
ps.path.getsize() |
獲取文件大小 |
shutil.copytree() |
複製文件夾 |
shutil.copyfile() |
複製文件 |
shutil.move() |
移動文件 |
os.rmdir() |
刪除目錄 |
|
|
1.4序列化操作
cPickle和pickle兩個模塊來實現序列化,前者由C語言編寫的,效率比後者高很多。
Pickle使用dumps方法將任意對象序列化成一個str。
1.5進程和線程
一種方法是使用os模塊中的fork方法,另一種方法是使用multiprocessing模塊。
getpid方法用於獲取當前進程的ID,getppid方法用於獲取父進程的ID。
start()方法啓動進程,用join()方法實現進程間的同步。
pool()可以提供指定數量的進程供用戶調用,默認大小是CPU的核數。
1.6進程間通信
Queue用在多個進程之間的數據傳遞。有兩個方法,put和get可以進行Queue操作。
|
blocked |
timeout |
|
Put |
True |
正值 |
該方法會阻塞timeout指定的時間,直到該隊列有剩餘的空間。如果超時會Queue.Full異常。 |
False |
NA |
Queue滿,Queue.Full異常 |
|
Get |
True |
正值 |
那麼在等待時間內沒有取得任何元素,會拋出Queue.Empty異常。 |
False |
有值 |
則立即返回該值。 |
|
空 |
則立即拋出Queue.Empty異常。 |
Pipe的通信機制常用來在兩個進程間進行通信,兩個進程分別位於管道的兩端。
Pipe |
Duplex |
|
False |
conn1只負責接收消息,conn2 只負責發送消息 |
|
True |
管道是全雙工模式,也就是說conn1和conn2均可收發 |
1.7多線程
Threading模塊一般通過兩種方式創建多線程:第一種方式是把一個函數傳入並創建Thread實例,然後調用start方法開始執行;第二種方式是直接從threading.Thread繼承並創建線程類,然後重寫_init_方法和run方法。
1.8線程同步
Thread對象的Lock和RLock可以實現簡單的線程同步,這兩個對象都有acquire方法和release方法,對於每次只允許一個線程操作的數據,可以將其操作放到qcuqire和release方法之間。
1.9協程
Python通過yield和gevent庫是更好的選擇,提供了比較完善的協程支持。gevent中的spawn方法可以看做是用來形成協程,joinall方法就是添加這些協程任務,並且啓動運行。
2.0分佈式進程
Multiprocessing模塊不但支持多進程,其中managers子模塊還支持把多進程分佈到多臺機器上。
2.1網絡編程
Socket類型
套接字格式爲:socket(family,type[,protocal]),使用給定的地址族、套接字類型、協議編號創建套接字。
Socket.AF_UNIX |
只能夠用於單一的Unix系統進程通信 |
Socket.AF_INET |
服務器之間網絡通信 |
Socket.AF_INET6 |
IPv6 |
Socket.SOCK_STREAM |
流式socket,用於TCP |
Socket.SOCK_DGRAM |
數據報式socket,用於UDP |
Socket.SOCK_RAW |
原始套接字,普通的套接字無法處理ICMP/IGMP等網絡報文,而SOCK_RAW可以;其次,SOCK_RAW也可以處理特殊的IPv4報文,此外,利用原始套接字,可以通過IP_HDRINCL套接字選項由用戶構造IP頭。 |
Socket.SOCK_SEQPACKET |
可靠的連續數據包服務 |
創建TCP socket |
S=socket.socket(socket.AF_INET,socket.SOCK_STREAM) |
創建UDP socket |
S=socket.socket(socket.AF_INET,socket.SOCK_DGREAM) |
Socket函數
Socket函數 |
描述 |
|
服務器socket函數 |
S.bind(address) |
將套接字綁定到地址,在AF_INET下,以元組(host,port)的形式表示地址 |
s.listen(backlog) |
開始監聽TCP傳入連接,backlog指定在拒絕連接之前,操作系統可以掛起的最大連接數量。該值至少爲1,大部分應用程序設爲5就可以了。 |
s.accept() |
接受TCP連接並返回(conn,address),其中conn是新的套接字對象,可以用來接收和發送數據address是連接客戶端的地址。 |
|
客戶端 |
S.connect(address) |
連接到address處的套接字。一般address的格式爲元組(hostname,port),如果連接出錯,返回socket.error錯誤 |
s.connect_ex(address) |
功能與connect(address)相同,但是返回0,失敗返回errno的值。 |
|
公共socket函數 |
s.recv(bufsize[,flag]) |
接受TCP套接字的數據,數據以字符串形式返回,bufsize指定要接收的最大數據量。Flag提供有關消息的其他信息,通常可以忽略 |
s.send(string[,flag]) |
發送TCP數據。將string中的數據發送到連接的嵌套字。返回值是要發送的字節數量,該數量可能小於string的字節大小。 |
s.sendall(string[,flag]) |
完整發送TCP數據。將string中的 數據發送到連接的套接字,但在返回之前會嘗試發送所有的數據。但成功返回None,失敗則拋出異常。 |
s.recvfrom(bufsize[,flag]) |
接受UDP套接字的數據。將string中的數據發送到連接的套接字。返回值是(data,address)。其中data是包含接收數據的字符串,address是發送數據的套接字地址 |
s.sendto(string[,flag],address) |
發送UDP數據。將數據發送到套接字,address是形式(ipaddr,port)的元組,指定遠程地址。返回值是發送的字節數。 |
s.close() |
關閉套接字 |
s.getpeername() |
返回連接套接字的遠程地址。返回值通常是元組(ipaddr,port) |
s.getsockname() |
返回套接字自己的地址。同常是一個元組(ipaddr,port) |
s.setsockopt(level,optname,value) |
設置給定套接字選項的值 |
s.getsockopt(level,optname,[.buflen]) |
返回套接字選項的值 |
s.settimeout(timeout) |
設置套接字操作的超時期,timeout是一個浮點數,單位是秒。值爲None表示沒有超時期。一般超時期應該在剛創建套接字時設置,因爲它們可能會用於連接操作。 |
s.setblocking(flag) |
如果flag爲0,則將套接字設爲非阻塞模式,否則將套接字設爲阻塞模式。非阻塞模式下,如果調用recv()沒有發現任何數據,或send()調用無法立即發送數據,將引起socket.error異常。 |
|
|
2.2 TCP編程
服務端 |
客戶端 |
1)創建Socket,綁定Socket到本地IP與端口 |
1)創建Socket,連接遠端地址。 |
2)開始監聽連接 |
2)連接後發送數據和接收數據 |
3)進入循環,不斷接收客戶端的連接請求 |
3)傳輸完畢後,關閉Socket |
4)接收傳來的數據併發送給對方數據 |
|
5)傳輸完畢後,關閉Socket |
|
|
|
UDP編程
1)創建Socket,綁定的IP和端口 |
1)創建Socket |
2)直接發送數據和接收數據 |
|
3)關閉socket |
|