Python開發基礎----異常處理、socket通訊端基礎1

來源:互聯網
上載者:User

標籤:選項   代碼塊   udp協議   run   protocal   pip   不能   accept   模組   

異常處理

錯誤

程式裡的錯誤一般分為兩種:

  1、語法錯誤,這種錯誤,根本過不了python解譯器的文法檢測,必須在程式執行前就改正

  2、邏輯錯誤,人為造成的錯誤,如資料類型錯誤、調用方法錯誤等,這些解譯器是不會進行檢測的,只有在執行的過程中才能拋出的錯誤

異常

異常是python解譯器在運行程式的過程中遇到錯誤所拋出的資訊,如:

Python異常種類:

常用異常:

 1 AttributeError     試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x 2 IOError     輸入/輸出異常;基本上是無法開啟檔案 3 ImportError     無法引入模組或包;基本上是路徑問題或名稱錯誤 4 IndentationError     語法錯誤(的子類) ;代碼沒有正確對齊 5 IndexError     下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5] 6 KeyError     試圖訪問字典裡不存在的鍵 7 KeyboardInterrupt     Ctrl+C被按下 8 NameError     使用一個還未被賦予對象的變數 9 SyntaxError     Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)10 TypeError     傳入物件類型與要求的不符合11 UnboundLocalError     試圖訪問一個還未被設定的局部變數,基本上是由於另有一個同名的全域變數,導致你以為正在訪問它12 ValueError     傳入一個調用者不期望的值,即使值的類型是正確的

其他異常:

 1 ArithmeticError 2 AssertionError 3 AttributeError 4 BaseException 5 BufferError 6 BytesWarning 7 DeprecationWarning 8 EnvironmentError 9 EOFError10 Exception11 FloatingPointError12 FutureWarning13 GeneratorExit14 ImportError15 ImportWarning16 IndentationError17 IndexError18 IOError19 KeyboardInterrupt20 KeyError21 LookupError22 MemoryError23 NameError24 NotImplementedError25 OSError26 OverflowError27 PendingDeprecationWarning28 ReferenceError29 RuntimeError30 RuntimeWarning31 StandardError32 StopIteration33 SyntaxError34 SyntaxWarning35 SystemError36 SystemExit37 TabError38 TypeError39 UnboundLocalError40 UnicodeDecodeError41 UnicodeEncodeError42 UnicodeError43 UnicodeTranslateError44 UnicodeWarning45 UserWarning46 ValueError47 Warning48 ZeroDivisionError

異常處理

預設情況下(非程式員使用raise觸發的異常),當執行的程式遇到錯誤拋出異常後會終止程式的運行,在錯誤點中斷,後面的代碼不會繼續執行。

異常處理是指通過指定的代碼進行異常捕捉,當捕捉到指定的異常類則進入特定的邏輯繼續執行,使得程式不會在錯誤點中斷運行,一般用來捕捉程式無法控制的異常錯誤(如用戶端異常中斷與伺服器端的串連導致伺服器端崩潰)。

if判斷式異常處理

通過邏輯判斷進行控制,想想曾經input+if的方式進行輸入檢測、防止語法錯誤的過程,但是這類if判斷式與原來的邏輯並無關係,所以會造成代碼可讀性差

try...except...異常處理

python定製的一個異常處理類,文法如下:

1 try:2     被檢測的代碼塊3 except 異常類型:4     try中一旦檢測到異常,如果這個異常和except標記的異常一樣,就執行這個位置的邏輯

樣本1:迭代器StopIteration異常處理

準備檔案a.txt,只有五行內容

1111111222222222222333333334444555555555

異常拋出:由於迭代器f沒有那麼多內容,所以第六個__next__會拋出StopIteration異常提示

1 f=open(‘a.txt‘,‘r‘)2 print(f.__next__())3 print(f.__next__())4 print(f.__next__())5 print(f.__next__())6 print(f.__next__())7 print(f.__next__())8 print(f.__next__())9 print(f.__next__())

異常處理:當碰到第六個__next__拋出異常後,except比較異常,如果一樣,那麼關閉檔案對象

 1 f=open(‘a.txt‘,‘r‘) 2 try: 3     print(f.__next__()) 4     print(f.__next__()) 5     print(f.__next__()) 6     print(f.__next__()) 7     print(f.__next__()) 8     print(f.__next__()) 9     print(f.__next__())10     print(f.__next__())11 except StopIteration:  #只能夠捕捉處理指定的StopIteration異常,如果是其他的異常則無法處理,依然會拋出錯誤12     f.close()

樣本2:多分支異常處理,程式碼片段中可能會出現多個異常類,而一個except只能指定一個異常,所以可以用多分支結構

 1 s=‘asdf‘ 2 l=[‘a‘] 3 d={‘name‘:‘bob‘} 4 try: 5     # int(s)    #ValueError 6     # l[2]      #IndexError 7     d[‘age‘]    #KeyError 8 except IndexError as e:  #as e表示將捕獲的IndexError錯誤資訊的異常值賦值給e 9     print(e)10 except KeyError as e:11     print(e)12 except ValueError as e:13     print(e)

樣本3:萬能異常,Exception,他可以捕獲任意異常

1 s=‘asdf‘2 l=[‘a‘]3 d={‘name‘:‘bob‘}4 try:5     int(s)    #ValueError6     l[2]      #IndexError7     d[‘age‘]    #KeyError8 except Exception as e:9     print(e)

注意:如果需求為所有的異常統一一段邏輯處理,那麼使用萬能異常,如果針對不同的異常有不同的處理邏輯,那麼使用多分支結構,多分枝結構的最後可以跟一個萬能異常處理分支

樣本4:異常的其他選項

 1 s=‘asdf‘ 2 l=[‘a‘] 3 d={‘name‘:‘bob‘} 4 try: 5     int(s)    #ValueError 6     l[2]      #IndexError 7     d[‘age‘]    #KeyError 8 except Exception as e: 9     print(e)10 else:11     print(‘try內代碼塊沒有異常則執行我‘)12 finally:13     print(‘無論異常與否,都會執行該模組,通常是進行清理工作,如關閉檔案、刪除對象‘) 

樣本5:主動觸發異常,人為產生一個異常

1 try:2     raise TypeError(‘類型錯誤‘)    #類型錯誤是所觸發的異常的值3 except Exception as e:4     print(e)5 6 輸出結果:7 類型錯誤

樣本6:自訂異常處理類

1 class DefaultException(BaseException):2     def __init__(self,msg):3         self.msg=msg4     def __str__(self):  #定義類本身的傳回值5         return self.msg6 try:7     raise DefaultException(‘類型錯誤‘)8 except DefaultException as e:9     print(e)    #DefaultException的傳回值

樣本7:斷言,類似於if判斷,不過斷言是絕對真,如果不是真就不會往下執行

1 a=12 b=23 assert a<b4 print(a+b)    #輸出結果35 assert a>b    #輸出結果:AssertionError異常錯誤6 print(b-a)    #沒執行

樣本8:try和if的比較,如果是if,需要每一個input都要做一次判斷,而try可以對所有的input做處理

1 try:2     num1=input(‘>>: ‘) 3     int(num1) #正統程式放到了這裡,其餘的都屬於異常處理範疇4     num2=input(‘>>: ‘) 5     int(num2)6     num3=input(‘>>: ‘) 7     int(num3)8 except ValueError as e:9     print(e)

使用try..except的方式(但是也別忘了if)

1:把錯誤處理和真正的工作分開來

2:代碼更易組織,更清晰,複雜的工作任務更容易實現;

3:毫無疑問,更安全了,不至於由於一些小的疏忽而使程式意外崩潰了;

只有在有些異常無法預知的情況下,才應該加上try...except,其他的邏輯錯誤應該盡量修正,盡量避免使用異常處理

 

通訊端基礎

C/S架構

即用戶端/服務端架構,B/S架構(瀏覽器/伺服器)也屬於C/S架構。

socket通訊端就是為了完成C/S架構軟體的開發。

socket基礎的基礎

socket依賴於網路,所以騷年,網路基礎不能忘了

socket介紹

在python裡,socket子層位於TCP/IP協議棧的傳輸層和應用程式層的中介層,是一個提供向上向下介面的軟體抽象層。

socket封裝了tcp和udp協議,所以遵循socket文法寫出的程式是遵循tcp和udp協議的。

注意:socket=ip+port,ip用來標識網路中主機的位置,port用來標識主機的應用,所以ip+port能夠標識互連網中的唯一一個應用,所以說socket其實就是ip和連接埠的組合

socket分類

網路編程只需要關注AF_INET,這種是應用最廣泛的,如果是用於ipv6平台需要用AF_INET6。

其他:AF_UNIX,用於UNIX檔案系統間通訊、還有很多其他的平台使用的,不多說

socket通訊原理

 

伺服器端先初始化Socket,然後與連接埠綁定(bind),對連接埠進行監聽(listen)並調用accept阻塞,等待用戶端串連。

用戶端初始化一個Socket,然後串連伺服器(connect),如果正常訪問到了伺服器端,伺服器端阻塞結束,串連成功,這時用戶端與伺服器端的串連就建立了。

用戶端發送資料請求,伺服器端接收請求並處理請求,然後伺服器把回應資料發送給用戶端,用戶端讀取資料,迴圈。

最後用戶端或者伺服器端關閉串連,一次互動結束。

 

socket模組

一次性通訊端通訊(基於本地迴環地址),以打電話的過程解釋

服務端:

import sockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #買手機s.bind((‘127.0.0.1‘,9000)) #手機插卡,如果元組為(‘‘,9000)表示本機所有的網卡,相當於0.0.0.0s.listen(5)     #手機待機,括弧中的值是用於TCP串連的最佳化conn,addr=s.accept()            #手機接電話print(‘接到來自%s的電話‘ %addr[0])msg=conn.recv(1024)             #聽訊息,聽話print(msg,type(msg))conn.send(msg.upper())          #發訊息,說話conn.close()                    #掛電話s.close()                       #手機關機

用戶端:

import sockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM)    #買手機s.connect_ex((‘127.0.0.1‘,9000))           #撥電話s.send(‘nb‘.encode(‘utf-8‘))         #發訊息,說話(只能發送位元組類型)feedback=s.recv(1024)               #收訊息,聽話print(feedback.decode(‘utf-8‘))s.close()                                       #掛電話

執行先執行服務端,然後執行用戶端。

相關值說明:

1 socket.socket(socket_family,socket_type,protocal=0)2 socket_family可以是 AF_UNIX 或 AF_INET3 socket_type 可以是 SOCK_STREAM(連線導向的可靠資料轉送,即TCP協議)或 SOCK_DGRAM(面向不需連線的不可靠資料轉送,即UDP)4 protocol 一般不填,預設值為 0

相關方法說明:

 1 服務端通訊端函數 2 s.bind()    綁定(主機,連接埠號碼)到通訊端 3 s.listen()  開始TCP監聽 4 s.accept()  被動接受TCP客戶的串連,(阻塞式)等待串連的到來 5  6 用戶端通訊端函數 7 s.connect()     主動初始化TCP伺服器串連 8 s.connect_ex()  connect()函數的擴充版本,出錯時返回出錯碼,而不是拋出異常 9 10 公用用途的通訊端函數11 s.recv()            接收TCP資料12 s.send()            發送TCP資料(send在待發送資料量大於己端緩衝區剩餘空間時,資料丟失,不會發完)13 s.sendall()         發送完整的TCP資料(本質就是迴圈調用send,sendall在待發送資料量大於己端緩衝區剩餘空間時,資料不丟失,迴圈調用send直到發完)14 s.recvfrom()        接收UDP資料15 s.sendto()          發送UDP資料16 s.getpeername()     串連到當前通訊端的遠端的地址17 s.getsockname()     當前通訊端的地址18 s.getsockopt()      返回指定通訊端的參數19 s.setsockopt()      設定指定通訊端的參數20 s.close()           關閉通訊端21 22 面向鎖的通訊端方法23 s.setblocking()     設定通訊端的阻塞與非阻塞模式24 s.settimeout()      設定阻塞通訊端操作的逾時時間25 s.gettimeout()      得到阻塞通訊端操作的逾時時間26 27 面向檔案的通訊端的函數28 s.fileno()          通訊端的檔案描述符29 s.makefile()        建立一個與該通訊端相關的檔案

socket迴圈通訊,即一個串連來了可以不斷的迴圈互動,有多個串連請求串連的時候如果第一個串連不中斷,則無法串連,當第一個串連中斷,第二個串連連上來,依次

伺服器端:

 1 import socket 2 s=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #買手機 3 s.bind((‘127.0.0.1‘,9000)) #手機插卡 4 s.listen(5)     #手機待機,括弧中的值是用於TCP串連的最佳化 5 while True: #可以不停的接電話,即不停地接受串連 6     conn,addr=s.accept()            #手機接電話 7     print(‘接到來自%s的電話‘ %addr[0]) 8     while True:  #迴圈的收發訊息 9         msg=conn.recv(1024)             #聽訊息,聽話10         print(msg,type(msg))11         conn.send(msg.upper())          #發訊息,說話12     conn.close()                    #掛電話13 s.close()                       #手機關機

用戶端:

import sockets=socket.socket(socket.AF_INET,socket.SOCK_STREAM) #買手機s.connect((‘127.0.0.1‘,9000)) #撥號while True: #通訊迴圈    msg=input(‘>>: ‘).strip()    if not msg:continue    s.send(msg.encode(‘utf-8‘))    server_res=s.recv(1024)    print(‘server_res: ‘,server_res.decode(‘utf-8‘))phone_client.close()

錯誤處理:

 

 由於服務端仍然存在四次揮手的time_wait狀態在佔用地址(如果不懂,請深入研究1.tcp三向交握,四次揮手 2.syn洪水攻擊 3.伺服器高並發情況下會有大量的time_wait狀態的最佳化方法)

解決

 windows linux

 

簡單SSH樣本

服務端

 1 import socket 2 import subprocess 3 ssh_server=socket.socket(socket.AF_INET,socket.SOCK_STREAM)   #產生socket執行個體對象 4 ssh_server.setsockopt(socket.SOL_SOCKET,socket.SO_REUSEADDR,1) #重用地址,防止佔用 5 ssh_server.bind((‘127.0.0.1‘,8080)) 6 ssh_server.listen(5) 7 print(‘server run...‘) 8 while True: 9     conn,client_addr=ssh_server.accept()  #迴圈等待串連10     print(‘用戶端: ‘,client_addr)11     while True: #通訊迴圈12         try:13             cmd=conn.recv(1024) #收訊息14             res=subprocess.Popen(cmd.decode(‘utf-8‘),       #執行命令15                              shell=True,16                              stdout=subprocess.PIPE,17                              stderr=subprocess.PIPE)18             stdout=res.stdout.read()    #標準輸出19             stderr=res.stderr.read()    #標準輸入20             std=stdout+stderr21             conn.sendall(std)22 23         except Exception:24             break25     conn.close()    #斷串連,進入下一次串連等待26 ssh_server.close() #關閉程式

用戶端:

 1 import socket 2 ssh_client=socket.socket(socket.AF_INET,socket.SOCK_STREAM) 3 ssh_client.connect((‘127.0.0.1‘,8080)) 4 while True: #通訊迴圈 5     cmd=input(‘>>: ‘).strip() 6     if not cmd:continue 7     ssh_client.send(cmd.encode(‘utf-8‘)) 8     cmd_res = ssh_client.recv(1024) 9     print(cmd_res.decode(‘gbk‘)) #windows10     # print(cmd_res.decode(‘utf-8‘)) #linux11 ssh_client.close()

Python開發基礎----異常處理、socket通訊端基礎1

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.