1、isinstance(obj, cls)python
檢查是否obj是不是類 cls 的對象編程
class Foo(object): pass obj = Foo() isinstance(obj, Foo)
2、issubclass(sub, super)服務器
檢查sub類是不是 super 類的派生類網絡
class Foo(object): pass class Bar(Foo): pass issubclass(Bar, Foo)
3、異常處理socket
一、異常基礎ide
在編程過程當中爲了增長友好性,在程序出現bug時通常不會將錯誤信息顯示給用戶,而是現實一個提示的頁面,通俗來講就是不讓用戶看見大黃頁!!!函數
二、異常種類編碼
python中的異常種類很是多,每一個異常專門用於處理某一項異常!!!spa
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 致使你覺得正在訪問它 13 ValueError 傳入一個調用者不指望的值,即便值的類型是正確的
ArithmeticError AssertionError AttributeError BaseException BufferError BytesWarning DeprecationWarning EnvironmentError EOFError Exception FloatingPointError FutureWarning GeneratorExit ImportError ImportWarning IndentationError IndexError IOError KeyboardInterrupt KeyError LookupError MemoryError NameError NotImplementedError OSError OverflowError PendingDeprecationWarning ReferenceError RuntimeError RuntimeWarning StandardError StopIteration SyntaxError SyntaxWarning SystemError SystemExit TabError TypeError UnboundLocalError UnicodeDecodeError UnicodeEncodeError UnicodeError UnicodeTranslateError UnicodeWarning UserWarning ValueError Warning ZeroDivisionError
萬能異常 在python的異常中,有一個萬能異常:Exception,他能夠捕獲任意異常,即:code
接下來你可能要問了,既然有這個萬能異常,其餘異常是否是就能夠忽略了!
答:固然不是,對於特殊處理或提醒的異常須要先定義,最後定義Exception來確保程序正常運行。
三、異常其餘結構
1 try: 2 # 主代碼塊 3 pass 4 except KeyError,e: 5 # 異常時,執行該塊 6 pass 7 else: 8 # 主代碼塊執行完,執行該塊 9 pass 10 finally: 11 # 不管異常與否,最終執行該塊 12 pass
四、主動觸發異常
五、自定義異常
class WupeiqiException(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message try: raise WupeiqiException('個人異常') except WupeiqiException,e: print e
六、斷言
# assert 條件
assert 1 == 1
assert 1 == 2
4、反射
python中的反射功能是由如下四個內置函數提供:hasattr、getattr、setattr、delattr,改四個函數分別用於對對象內部執行:檢查是否含有某成員、獲取成員、設置成員、刪除成員。
class Foo(object): def __init__(self): self.name = 'wupeiqi' def func(self): return 'func' obj = Foo() # #### 檢查是否含有成員 #### hasattr(obj, 'name') hasattr(obj, 'func') # #### 獲取成員 #### getattr(obj, 'name') getattr(obj, 'func') # #### 設置成員 #### setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 刪除成員 #### delattr(obj, 'name') delattr(obj, 'func')
-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
1、概述
socket一般也稱做"套接字",用於描述IP地址和端口,是一個通訊鏈的句柄,應用程序一般經過"套接字"向網絡發出請求或者應答網絡請求。
socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,對於文件用【打開】【讀寫】【關閉】模式來操做。 socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉)
socket和file的區別:
WEB服務應用:
#!/usr/bin/env python #coding:utf-8 import socket def handle_request(client): buf = client.recv(1024) client.send("HTTP/1.1 200 OK\r\n\r\n") client.send("Hello, World") def main(): sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM) sock.bind(('localhost',8080)) sock.listen(5) while True: connection, address = sock.accept() handle_request(connection) connection.close() if __name__ == '__main__': main()
2、解釋
sk = socket.socket(socket.AF_INET,socket.SOCK_STREAM,0)
參數一:地址簇
socket.AF_INET IPv4(默認)
socket.AF_INET6 IPv6
socket.AF_UNIX 只可以用於單一的Unix系統進程間通訊
參數二:類型
socket.SOCK_STREAM 流式socket , for TCP (默認)
socket.SOCK_DGRAM 數據報式socket , for UDP
socket.SOCK_RAW 原始套接字,普通的套接字沒法處理ICMP、IGMP等網絡報文,而SOCK_RAW能夠;其次,SOCK_RAW也能夠處理特殊的IPv4報文;此外,利用原始套接字,能夠經過IP_HDRINCL套接字選項由用戶構造IP頭。
socket.SOCK_RDM 是一種可靠的UDP形式,即保證交付數據報但不保證順序。SOCK_RAM用來提供對原始協議的低級訪問,在須要執行某些特殊操做時使用,如發送ICMP報文。SOCK_RAM一般僅限於高級用戶或管理員運行的程序使用。
socket.SOCK_SEQPACKET 可靠的連續數據包服務
參數三:協議
0 (默認)與特定的地址家族相關的協議,若是是 0 ,則系統就會根據地址格式和套接類別,自動選擇一個合適的協議
import socket ip_port = ('127.0.0.1',9999) sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0) sk.bind(ip_port) while True: data = sk.recv(1024) print data import socket ip_port = ('127.0.0.1',9999) sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0) while True: inp = raw_input('數據:').strip() if inp == 'exit': break sk.sendto(inp,ip_port) sk.close()
sk.bind(address)
s.bind(address) 將套接字綁定到地址。address地址的格式取決於地址族。在AF_INET下,以元組(host,port)的形式表示地址。
sk.listen(backlog)
開始監聽傳入鏈接。backlog指定在拒絕鏈接以前,能夠掛起的最大鏈接數量。
backlog等於5,表示內核已經接到了鏈接請求,但服務器尚未調用accept進行處理的鏈接個數最大爲5
這個值不能無限大,由於要在內核中維護鏈接隊列
sk.setblocking(bool)
是否阻塞(默認True),若是設置False,那麼accept和recv時一旦無數據,則報錯。
sk.accept()
接受鏈接並返回(conn,address),其中conn是新的套接字對象,能夠用來接收和發送數據。address是鏈接客戶端的地址。
接收TCP 客戶的鏈接(阻塞式)等待鏈接的到來
sk.connect(address)
鏈接到address處的套接字。通常,address的格式爲元組(hostname,port),若是鏈接出錯,返回socket.error錯誤。
sk.connect_ex(address)
同上,只不過會有返回值,鏈接成功時返回 0 ,鏈接失敗時候返回編碼,例如:10061
sk.close()
關閉套接字
sk.recv(bufsize[,flag])
接受套接字的數據。數據以字符串形式返回,bufsize指定最多能夠接收的數量。flag提供有關消息的其餘信息,一般能夠忽略。
sk.recvfrom(bufsize[.flag])
與recv()相似,但返回值是(data,address)。其中data是包含接收數據的字符串,address是發送數據的套接字地址。
sk.send(string[,flag])
將string中的數據發送到鏈接的套接字。返回值是要發送的字節數量,該數量可能小於string的字節大小。
sk.sendall(string[,flag])
將string中的數據發送到鏈接的套接字,但在返回以前會嘗試發送全部數據。成功返回None,失敗則拋出異常。
sk.sendto(string[,flag],address)
將數據發送到套接字,address是形式爲(ipaddr,port)的元組,指定遠程地址。返回值是發送的字節數。該函數主要用於UDP協議。
sk.settimeout(timeout)
設置套接字操做的超時期,timeout是一個浮點數,單位是秒。值爲None表示沒有超時期。通常,超時期應該在剛建立套接字時設置,由於它們可能用於鏈接的操做(如 client 鏈接最多等待5s )
sk.getpeername()
返回鏈接套接字的遠程地址。返回值一般是元組(ipaddr,port)。
sk.getsockname()
返回套接字本身的地址。一般是一個元組(ipaddr,port)
sk.fileno()
套接字的文件描述符
1、使用以源碼剖析
對於默認Socket服務端處理客戶端請求時,按照阻塞方式依次處理請求,SocketServer實現同事處理多個請求。
#!/usr/bin/env python #coding:utf-8 import SocketServer import os class MyServer(SocketServer.BaseRequestHandler): def handle(self): base_path = 'G:/temp' conn = self.request print 'connected...' while True: pre_data = conn.recv(1024) #獲取請求方法、文件名、文件大小 cmd,file_name,file_size = pre_data.split('|') # 防止粘包,給客戶端發送一個信號。 conn.sendall('nothing') #已經接收文件的大小 recv_size = 0 #上傳文件路徑拼接 file_dir = os.path.join(base_path,file_name) f = file(file_dir,'wb') Flag = True while Flag: #未上傳完畢, if int(file_size)>recv_size: #最多接收1024,可能接收的小於1024 data = conn.recv(1024) recv_size+=len(data) #寫入文件 f.write(data) #上傳完畢,則退出循環 else: recv_size = 0 Flag = False print 'upload successed.' f.close() instance = SocketServer.ThreadingTCPServer(('127.0.0.1',9999),MyServer) instance.serve_forever()
#!/usr/bin/env python #coding:utf-8 import socket import sys import os ip_port = ('127.0.0.1',9999) sk = socket.socket() sk.connect(ip_port) container = {'key':'','data':''} while True: # 客戶端輸入要上傳文件的路徑 input = raw_input('path:') # 根據路徑獲取文件名 file_name = os.path.basename(path) # 獲取文件大小 file_size=os.stat(path).st_size # 發送文件名 和 文件大小 sk.send(file_name+'|'+str(file_size)) # 爲了防止粘包,將文件名和大小發送過去以後,等待服務端收到,直到從服務端接受一個信號(說明服務端已經收到) sk.recv(1024) send_size = 0 f= file(path,'rb') Flag = True while Flag: if send_size + 1024 >file_size: data = f.read(file_size-send_size) Flag = False else: data = f.read(1024) send_size+=1024 sk.send(data) f.close() sk.close()
對於大文件處理:
send只會向緩衝區寫一次,傳入的內容不必定能發完,因此,返回值是實際發送的大小。 例如: 1023M = send(1g數據) 那麼實際是發送了 1023M,其餘 1M 就是漏發了 sendall,內部調用send會一直向緩衝區寫,直到文件所有寫完。 例如: sendall(1g數據) 第一次: send(1023M) 第二次: send(1M) ========== 發送大文件時候,不可能所有讀1G內存,須要open文件時,一點一點讀,而後再發。 # 大文件大小 file_size=os.stat(文件路徑).st_size # 打開大文件 f = file(文件路徑,'rb') # 已經發送的數據 send_size = 0 while Flag: # 大文件只剩下 不到 1024 字節,其餘已經被髮送。 if send_size + 1024 > file_size: # 從大文件中讀取小於 1024字節,多是 10字節... data = f.read(file_size-send_size) Flag = False else: # 從大文件中讀取 1024 字節 data = f.read(1024) # 記錄已經發送了多少字節 send_size += 1024 # 將大文件中的數據,分批發送到緩衝區,每次最多發 1024 字節 sk.sendall(data)