知識點概覽:python
1、靜態方法:@staticmethod編程
只是名義上歸類管理,實際上在靜態方法裏訪問不了類或者實例中的任何屬性。也能夠說跟類沒什麼關係了,也就是截斷了跟類的關聯,實際上也就是一個函數而已。服務器
實際場景就能夠用它來作個工具包 網絡
#!/usr/bin/env python # -*- coding:utf-8 -*- class Dog(object): def __init__(self,name): self.name = name @staticmethod # def eat(self,food): # print("%s is eating %s"%(self.name,food)) def eat(self): print("%s is eating %s"%(self.name,'試試')) d = Dog("hehe") #d.eat() #原始調用能夠執行 d.eat(d) #調用靜態方法
2、類方法:只能訪問類變量,不能訪問實例變量併發
就好比說是修改國籍同樣,不讓改國籍,因此就直接建立一個寫死的類變量,再怎麼實例化也改不了socket
#!/usr/bin/env python # -*- coding:utf-8 -*- class Dog(object): name = 123 #定義類變量 def __init__(self,name): self.name = name @classmethod #類方法 def eat(self): print("%s is eating %s"%(self.name,'sss')) def talk(self): print("%s is talking..."%self.name) d = Dog("hehe") d.eat()
3、屬性方法:就是把一個方法變成靜態屬性函數
#!/usr/bin/env python # -*- coding:utf-8 -*- class Dog(object): def __init__(self,name): self.name = name self.__food = None #實例化一個私有屬性 @property #先把一個方法變成一個屬性,而後修改。。 def eat(self): print("%s is eating %s"%(self.name,self.__food)) @eat.setter #實例化的時候賦值 def eat(self,food): self.__food = food print("set to food ",food) @eat.deleter #實現對屬性方法的刪除操做 def eat(self): del self.__food print("刪完了私有屬性food") def talk(self): print("%s is talking"%self.name) d = Dog("hihi") #d.eat() #不可以被調用 d.eat #若是要傳參數的話那就比較尷尬了,由於不能調用啊。須要setter來輔助實現 d.eat = "呵呵噠" #輔助實現參數傳 遞 #del d.name #刪除實例變量 #print(d.name) #打印參數 d.eat del d.eat #默認的話不能刪除屬性方法,若是要實現的話須要在setter中刪除
使用場景:好比說三方軟件對航空公司的接口調用,實現查詢結果的進一步解析,提取出所需的信息,而後再經過可視化的方式傳遞給用戶 工具
#!/usr/bin/env python # -*- coding:utf-8 -*- class Flight(object): #定義一個航班類 def __init__(self,name): #初始化(實例化)參數 self.name = name #實例化參數的傳遞 def check_status(self): #航空公司狀態定義 print("checking flight %s status "%self.name) return 2 @property #屬性方法的調用 def flight_status(self): #對航空公司給的數據加以處理 status = self.check_status() if status == 0: print("flight canceled!!!") elif status == 1: print("flight already alive!!") elif status == 2: print("flight is comming!!") else: print("unrecognised status!!!") @flight_status.setter #狀態屬性的修改裝飾器 def flight_status(self,status): print("flight %s has changed status to %s"%(self.name,status)) f = Flight("ACC123") #定義要查的航線 f.flight_status #調用航空狀態 f.flight_status = 0 #實現對狀態的修改
4、類的特殊方法大數據
#!/usr/bin/env python # -*- coding:utf-8 -*- #類的普通方式 class Foo(object): def __init__(self,name): self.name = name f = Foo("jack") print(type(f)) #f以後的類是Foo print(type(Foo)) #Foo以後的類是type #類的裝逼方式 def func(self): #self是爲了了以後裝配到類中 print("hello world!!") Foo = type('Foo',(),{'funcs':func}) #定義一個Foo的對象,其實也就是類 print(type(Foo)) f = Foo() #實例化Foo f.funcs() #調用類的方法
得出的結論是:類來源於typeui
呵呵:這就是生命的起源
#!/usr/bin/env python # -*- coding:utf-8 -*- def func(self): #類裏面的方法 print("hello world!!%s"%self.name) def __init__(self,name,age): #初始化參數 self.name = name self.age = age Foo = type('Foo',(object,),{'funcs':func,'__init__':__init__}) #定義類 f = Foo("nimei",23) #實例化 f.funcs() #方法調用
#!/usr/bin/env python # -*- coding:utf-8 -*- class Mytype(object): def __init__(self,what,bases=None,dict=None): print("--mytype init--") super(Mytype, self).__init__(what,bases,dict) def __call__(self, *args, **kwargs): print("--Mytype call--") class Foo(object): __metaclass__ = Mytype def __init__(self,name): self.name = name print("Foo --init__") def __new__(cls,*args,**kwargs): print("Foo --new--") return object.__new__(cls) #new是自帶的方法 18
5、反射
經過字符串映射或者修改程序運行時的狀態,屬性,方法
hasattr(obj,name_str):判斷一個對象obj裏是否有對應的字符串name_str的方法映射
getattr(obj,name_str):根據字符串去獲取obj對象裏對應方法的內存地址
setattr(obj,name_str,z):經過字符串z,設置新的屬性
delattr(obj,name_str):根據name_str刪除obj一個屬性
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui def bulk(self): #添加新的屬性須要單獨在類外面定義一個方法 print("%s is bulking..."%self.name) class Dog(object): def __init__(self,name): self.name = name def eat(self,food): print("%s is eating"%self.name,food) d = Dog("hehe") choice = input("輸入>>:").strip() if hasattr(d,choice): #判斷一個對象d裏是否有對應的字符串choice的方法映射 func = getattr(d,choice) #根據字符串去獲取d對象裏對應方法的內存地址 # func("呵呵") #根據方法傳入類裏面定義的參數 setattr(d,choice,"cccc") # 修改傳入的參數 delattr(d,choice) #刪除傳入的參數 else: # setattr(d,choice,bulk) # d.talk(d) #方法調用 setattr(d,choice,1234) #添加新屬性1234 print(getattr(d,choice)) print(d.name) #打印類裏面的參數對應的值(上面if語句中的setattr裏的cccc)
6、異常處理
做用是:雖然程序出錯了,可是不想讓用戶看到這個報錯
格式: try: code #執行代碼 except (Error1,Error2) as e: #兩個錯誤定義 print(e) #打印錯誤,也可定義處理方式 #多種異常 except Exception as w: #多個錯誤定義(通常建議最後在用,定義未知錯誤) print(w) #打印錯誤,也可定義處理方式
例子:
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui names = ['memeda','mengmengda','heheda'] data = {} #names[4] #異常:IndexError: list index out of range #data['name'] #KeyError: 'name' #兩種錯誤的處理 try: names[4] #嘗試執行names[4] data['name'] open("hehehhe") # except IndexError as e: #若是有IndexError報錯的話執行下面的操做 # print('沒有你要找的key:',e) # except KeyError as e: # print("字典的key不存在",e) #或者將上述的兩個except組合 except (KeyError,IndexError) as e: #組合:只能抓到第一個錯 print("只能抓到第一個錯%e",e) #多種錯誤的處理( 通常最後位置用):抓住全部的錯誤 except Exception as e: print("未知錯誤%s",e) else: print("一切正常!!") finally: print("無論有沒有錯都執行!!")
常見的異常類型:
AttributeError 試圖訪問一個對象沒有的樹形,好比foo.x,可是foo沒有屬性x IOError 輸入/輸出異常;基本上是沒法打開文件 ImportError 沒法引入模塊或包;基本上是路徑問題或名稱錯誤 IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊 IndexError 下標索引超出序列邊界,好比當x只有三個元素,卻試圖訪問x[5] KeyError 試圖訪問字典裏不存在的鍵 KeyboardInterrupt Ctrl+C被按下 NameError 使用一個還未被賦予對象的變量 SyntaxError Python代碼非法,代碼不能編譯(我的認爲這是語法錯誤,寫錯了) TypeError 傳入對象類型與要求的不符合 UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是因爲另有一個同名的全局變量, 致使你覺得正在訪問它 ValueError 傳入一個調用者不指望的值,即便值的類型是正確的 經常使用異常
自定義異常
#!/usr/bin/env python # -*- coding:utf-8 -*- #Author:wanghui class TmpError(Exception): #自定義異常類 def __init__(self,msg): self.msg = msg def __str__(self): #類的格式返回函數 return self.msg try: raise TmpError('自定義異常!!') #觸發異常 except TmpError as e: print('自定義的錯誤%s',e)
7、socket網絡基礎:
Python 提供了兩個基本的 socket 模塊。
第一個是 Socket,它提供了標準的 BSD Sockets API。
第二個是 SocketServer, 它提供了服務器中心類,能夠簡化網絡服務器的開發。
下面講的是Socket模塊功能
套接字格式:
socket(family,type[,protocal]) 使用給定的地址族、套接字類型、協議編號(默認爲0)來建立套接字。
socket類型 |
描述 |
socket.AF_UNIX |
只可以用於單一的Unix系統進程間通訊 |
socket.AF_INET |
服務器之間網絡通訊 |
socket.AF_INET6 |
IPv6 |
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_SEQPACKET |
可靠的連續數據包服務 |
建立TCP Socket: |
|
建立UDP Socket: |
s=socket.socket(socket.AF_INET,socket.SOCK_DGRAM) |
注意點:
1)TCP發送數據時,已創建好TCP鏈接,因此不須要指定地址。UDP是面向無鏈接的,每次發送要指定是發給誰。
2)服務端與客戶端不能直接發送列表,元組,字典。須要字符串化repr(data)。
socket函數 |
描述 |
|
服務端socket函數 |
||
s.bind(address) |
將套接字綁定到地址, 在AF_INET下,以元組(host,port)的形式表示地址. |
|
s.listen(backlog) |
開始監聽TCP傳入鏈接。backlog指定在拒絕鏈接以前,操做系統能夠掛起的最大鏈接數量。該值至少爲1,大部分應用程序設爲5就能夠了。 |
|
s.accept() |
接受TCP鏈接並返回(conn,address),其中conn是新的套接字對象,能夠用來接收和發送數據。address是鏈接客戶端的地址。 |
|
客戶端socket函數 |
||
s.connect(address) |
鏈接到address處的套接字。通常address的格式爲元組(hostname,port),若是鏈接出錯,返回socket.error錯誤。 |
|
s.connect_ex(adddress) |
功能與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套接字的數據。與recv()相似,但返回值是(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表示沒有超時期。通常,超時期應該在剛建立套接字時設置,由於它們可能用於鏈接的操做(如connect()) |
|
s.gettimeout() |
返回當前超時期的值,單位是秒,若是沒有設置超時期,則返回None。 |
|
s.fileno() |
返回套接字的文件描述符。 |
|
s.setblocking(flag) |
若是flag爲0,則將套接字設爲非阻塞模式,不然將套接字設爲阻塞模式(默認值)。非阻塞模式下,若是調用recv()沒有發現任何數據,或send()調用沒法當即發送數據,那麼將引發socket.error異常。 |
|
s.makefile() |
建立一個與該套接字相關連的文件 |
TCP服務端:
1 建立套接字,綁定套接字到本地IP與端口
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.bind()
2 開始監聽鏈接 #s.listen()
3 進入循環,不斷接受客戶端的鏈接請求 #s.accept()
4 而後接收傳來的數據,併發送給對方數據 #s.recv() , s.sendall()
5 傳輸完畢後,關閉套接字 #s.close()
TCP客戶端:
1 建立套接字,鏈接遠端地址
# socket.socket(socket.AF_INET,socket.SOCK_STREAM) , s.connect()
2 鏈接後發送數據和接收數據 # s.sendall(), s.recv()
3 傳輸完畢後,關閉套接字 #s.close()