目錄python
try的工做原理是,當開始一個try語句後,python就在當前程序的上下文中做標記,這樣當異常出現時就能夠回到這裏,try子句先執行,接下來會發生什麼依賴於執行時是否出現異常。
代碼示例:服務器
while True: n1 = input('input a number: ') n2 = input('input a number: ') try: n1 = int(n1) n2 = int(n2) res = n1 + n2 print(res.sd) l = [1,2,3,4,] print(l[10]) d = {1:'a',2:'b'} print(d[3]) print('num:%s' %res) except ArithmeticError as e: #引用屬性錯誤 print('ArithmeticError') except IndexError as e: #下標錯誤 print('IndexError') except KeyError as e: #key錯誤 print('KeyError') except ValueError as e: #引用的值錯誤 print('ValueError',e) except Exception as e: #拋出絕大部分的錯誤 print('異常錯誤') print(e)
經過建立一個新的異常類,程序能夠命名它們本身的異常。異常應該是典型的繼承自Exception類,經過直接或間接的方式。網絡
#自定義異常 class DemoException(Exception): def __init__(self,msg): self.message = msg def __str__(self): return self.message a = 1 try: #若是不知足該條件,拋出異常 assert a == 1 except DemoException as e: print(e) else: print('ok') #不管是否存在異常,都執行finally finally: print('over')
socketserver 是標準庫中一個高級別的模塊,用於簡化網絡客戶與服務器的實現。
一、要實現本模塊,必須定義一個繼承於基類BaseRequestHandler的處理程序類。BaseRequestHandler類的實例能夠實現如下方法:
一、h.handle() 調用該方法執行實際的請求操做。調用該函數能夠不帶任何參數,可是幾個實例變量包含有用的值。h.request包含請求,h.client_address包含客戶端地址,h.server包含調用處理程序的實例。對TCP之類的數據流服務,h.request屬性是套接字對象。對於數據報服務,它是包含收到數據的字節字符串。
2.h.setup()該方法在handle()以前調用。默認狀況下,它不執行任何操做。若是但願服務器實現更多鏈接設置,能夠在這裏實現。
3.h.finish()調用本方法能夠在執行完handle()以後執行清除操做。若是setup()和 handle()都不生成異常,則無需調用該方法。
2.服務器。要使用處理程序,必須將其插入到服務器對象。定義了四個基本的服務器類。
一、TCPServer 支持ipv4的TCP協議的服務器。
二、UDPServer 支持ipv4的UDP協議的服務器。
三、UnixStreamServer 使用UNIX域套接字實現面向數據流協議的服務器,集成自TCPserver。
四、UnixDatagramServer 繼承自UDPServer
四個服務器類的實例都有一下方法和變量:
一、s.socket 用於傳入請求的套接字對象
二、s.server_address 監聽服務器的地址
三、s.RequestHandleClass 傳遞給服務器構造函數並由用戶提供的請求處理程序類
四、s.server_forever() 處理無線的請求
五、s.shutdown() 中止server_forever()循環
六、s.fileno() 返回服務器套接字的整數文件描述符。該方法能夠有效的經過輪詢操做實例
代碼實例
多線程
server端 #導入該模塊 import socketserver #定義一個類,繼承socketserver.BaseRequestHandler class Server(socketserver.BaseRequestHandler): def handle(self): #打印客戶端地址和端口 print('New connection:',self.client_address) #循環 while True: #接收客戶發送的數據 data = self.request.recv(1024) if not data:break#若是接收數據爲空就跳出,不然打印 print('Client data:',data.decode()) self.request.send(data)#將收到的信息再發送給客戶端 if __name__ == '__main__’: host,port = '127.0.0.1’,8080 #定義服務器地址和端口 server = socketserver.ThreadingTCPServer((host,port),Server) #實現了多線程的socket通話 server.serve_forever()#不會出如今一個客戶端結束後,當前服務器端就會關閉或者報錯,而是繼續運行,與其餘的客戶端繼續進行通話。 client端 import socket ip_port = ('127.0.0.1',8080) sk = socket.socket() sk.connect(ip_port) while True: raw = input('>> ').strip() sk.send(bytes(raw,'utf8')) msg = sk.recv(1024) print(str(msg,'utf8')) sk.close()
一、定義
進程是具備必定獨立功能的程序,關於某個數據集合上的一次運行活動。進程是系統進行資源分配和調度的一個獨立單位。
線程是進程的一個實體,是CPU調度和分配的基本單位,它是比進程更小的可以獨立運行的基本單位。線程不擁有系統資源,可是能夠和同屬一個進程的其餘線程貢獻進程所擁有的所有資源。
二、關係
一個線程能夠建立和銷燬另外一個線程;同一個進程中的多個線程之間能夠併發執行。
三、最大差異在於它們是不一樣的資源管理方式。進程有獨立的地址空間,一個進程崩潰後,不會對其它進程產生影響,而線程只是一個進程中的不一樣執行路徑。線程有本身的堆棧和局部變量,但沒有單獨的地址空間。所以一個線程死掉等於整個進程死掉,多以多進程的程序要比多線程的程序強壯,但進程切換時耗費資源比較大。對於一些要求同事進行又要共享某些變量的併發操做,只能用線程,不能用進程。
Python threading模塊
threading提供了一個比thread模塊更高層的API來提供線程的併發性。這些線程併發運行並共享內存。
1、Thread的使用
目標函數能夠實例化一個Thread對象,每一個Thread對象表明着一個線程,能夠經過start()方法,開始運行。
有兩種方式來建立線程:一種是經過繼承Thread類,重寫它的run方法;另外一種是建立一個threading.Thread對象,在它的初始化函數(__init__)中將可調用對象做爲參數傳入。併發
import threading import time def sayhi(num): print('running on nuber:%s' %num) time.sleep(3) if __name__ == '__main__': t1 = threading.Thread(target=sayhi,args=(1,)) t2 = threading.Thread(target=sayhi,args=(2,)) t1.start() t2.start() print(t1.getName()) print(t2.getName()) import threading import time def sayhi(num): print('running on nuber:%s' %num) time.sleep(3) if __name__ == '__main__’: t_list = [] for i in range(20): t = threading.Thread(target=sayhi,args=[i,]) t.start() t_list.append(t) for i in t_list: i.join() print('----done——')
threading模塊中的join函數
該函數的做用主要是阻塞進程直到線程執行完畢。通用的作法是啓動一批線程,最後join這些線程結束。
原理就是一次檢驗線程池中的線程是否結束,沒有結束就阻塞知道線程結束,若是結束則跳轉執行下一個線程的join函數。
endapp