Python學習心路歷程-day7

學習內容:html

1.類的特殊成員方法python

2.反射程序員

3.異常處理編程

4.Socket網絡編程開發基礎服務器

 

1.類的特殊成員方法                                                                            網絡

__doc__ 表示類的描述信息socket

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Foo:
  4     """類的描述信息,就是__doc__"""
  5     def func(self):
  6         pass
  7 print Foo.__doc__
__module__ 和  __class__ 

  __module__ 表示當前操做的對象在那個模塊ide

  __class__     表示當前操做的對象的類是什麼函數

__init__ 構造方法,經過類建立對象時,自動觸發執行。學習

__del__

析構方法,當對象在內存中被釋放時,自動觸發執行。

注:此方法通常無須定義,由於Python是一門高級語言,程序員在使用時無需關心內存的分配和釋放,由於此工做都是交給Python解釋器來執行,因此,析構函數的調用是由解釋器在進行垃圾回收時自動觸發執行的。

__call__ 對象後面加括號,觸發執行

注:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()

  1 #__call__
  2 # 注:構造方法的執行是由建立對象觸發的,即:對象 = 類名() ;而對於 __call__ 方法的執行是由對象後加括號觸發的,即:對象() 或者 類()()
  3 class Dog:
  4     def __init__(self,name):
  5         self.name = name
  6     def bulk(self):
  7         print("%s 汪~汪~汪" %(self.name))
  8     def __call__(self, *args, **kwargs):
  9         print "I am call",args,kwargs
 10 d1 = Dog("旺旺")
 11 d1("aaa","bbb","cccc")

__dict__ 查看類或對象中的全部成員

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Province:
  4     country = 'China'
  5     def __init__(self, name, count):
  6         self.name = name
  7         self.count = count
  8     def func(self, *args, **kwargs):
  9         print 'func'
 10 # 獲取類的成員,即:靜態字段、方法、
 11 print Province.__dict__
 12 # obj1 = Province('HuBei',10000)
 13 # print obj1.__dict__
 14 # 獲取 對象obj1 的成員
 15 obj2 = Province('HuNan', 3888)
 16 # print obj2.__dict__
 17 # 獲取 對象obj1 的成員

__str__ 若是一個類中定義了__str__方法,那麼在打印對象時,默認輸出該方法的返回值。

python3中使用,python建議使用__unicode__

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 class Role(object):
  4     def __init__(self,name,role,weapon,life_value=100,money=15000):
  5         self.name = name
  6         self.role = role
  7         self.weapon = weapon
  8         self.life_value = life_value
  9         self.money = money
 10     def shot(self):
 11         print("shooting...")
 12     def got_shot(self):
 13         print("%s: ah...,I got shot..."%self.name)
 14     def buy_gun(self,gun_name):
 15         print("just bought %s" %gun_name)
 16     # def __str__(self):
 17     #     print("name is %s"%self.name)
 18     #     return "name is %s"%self.name
 19
 20 r1 = Role("A","P","Ak47")
 21 print(r1)

__getitem____setitem____delitem__

用於索引操做,如字典。以上分別表示獲取、設置、刪除數據

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 #把這個實例變成字典
  4 class Foo(object):
  5     def __init__(self):
  6         self.data = {}
  7     def __getitem__(self, key):
  8         print('__getitem__',key)   #('__getitem__', 'name')
  9         return self.data.get(key)
 10     def __setitem__(self, key, value):
 11         print('__setitem__',key,value)
 12         self.data[key] = value
 13     def __delitem__(self, key):
 14         print('__delitem__',key)
 15
 16
 17 obj = Foo()   #實例化後,就成了字典
 18 obj["name"] = "lw"  #能夠像字典同樣賦值,自動觸發執行 __setitem__
 19 result = obj['name']      # 自動觸發執行 __getitem__
 20 print(result)
 21 print(obj.data)    #打印這個字典
 22 del obj['name']    #只是觸發__delitem__,並無真的刪除,要想刪除在__delitem__這個函數下面刪除,若是不想讓用戶刪除某些key,能夠加判斷
 23 print(obj.data)
 24 # del obj['k1']

2.反射                                                                                              

經過字符串映射或修改程序運行時的狀態、屬性、方法, 有如下4個方法

hasattr:判斷object中有沒有一個name字符串對應的方法或屬性

getattr:根據字符串去獲取對象裏的方法對應的內存地址

setattr :s equivalent to ``x.y = v''

delattr(x, y)

例1:

  1 # _*_ coding:utf-8 _*_
  2 __author__ = 'cs'
  3 def bulk(self):   #這裏會將函數設置成類裏面的方法
  4     print("%s is bulking"%self.name)
  5 class Dog(object):
  6
  7     def __init__(self,name):
  8         self.name = name
  9     def eat(self,age):
 10
 11         print("%s is eating.."%self.name)
 12
 13 d = Dog("金毛")
 14 # d.eat()
 15 choice = raw_input(">>>:").strip()
 16 # d.choice  想實現這種調用,根據用戶輸入調用方法,可是不能這麼寫,由於choic是個字符串
 17 print(hasattr(d,choice))    #查看類中是否有用戶輸入的方法或者屬性,有打印True,沒有打印False
 18 # print(getattr(d,choice))    #這樣會打印這個方法的內存地址,加上()就調用了
 19 # getattr(d,choice)()        #調用
 20 #------------------------------
 21 # print(d.name)
 22 # setattr(d,"name",choice)
 23 # print(d.name)
 24 #-------------------------------
 25 # setattr(d,choice,"22")
 26 # print(getattr(d,choice))
 27 # print(hasattr(d,choice))
 28 #------------------------------
 29 #動態添加變量
 30 # if hasattr(d,choice):
 31 #     getattr(d,choice)
 32 # else:
 33 #     setattr(d,choice,"ccc")
 34 #     V = getattr(d,choice)
 35 #     print(V)
 36 #---------------------------
 37 #動態設置方法,不管用戶輸入什麼,都不會報錯,均可以調用方法
 38 # if hasattr(d,choice):
 39 #     getattr(d,choice)
 40 # else:
 41 #     setattr(d,choice,bulk)   #d.talk == bulk
 42 #     func = getattr(d,choice)   #獲取choic的內存地址
 43 #     func(d)
 44
 45 # ----------------------
 46 # print(hasattr(d,choice))
 47 # getattr(d,choice)()
 48 # print(d.name)
 49 # if hasattr(d,choice):
 50 #     delattr(d,choice)
 51 # else:
 52 #     print("dont")
 53 # print(d.name)
 54 # delattr(d,choice)
 55 # if hasattr(d,choice):
 56 #     getattr(d,choice)()
 57 #
 58 # else:
 59 #     # print("沒有這個方法")

例2:

  1 class Foo(object):
  2 
  3     def __init__(self):
  4         self.name = 'wupeiqi'
  5 
  6     def func(self):
  7         return 'func'
  8 
  9 obj = Foo()
 10 
 11 # #### 檢查是否含有成員 ####
 12 hasattr(obj, 'name')
 13 hasattr(obj, 'func')
 14 
 15 # #### 獲取成員 ####
 16 getattr(obj, 'name')
 17 getattr(obj, 'func')
 18 
 19 # #### 設置成員 ####
 20 setattr(obj, 'age', 18)
 21 setattr(obj, 'show', lambda num: num + 1)
 22 
 23 # #### 刪除成員 ####
 24 delattr(obj, 'name')
 25 delattr(obj, 'func')
View Code

例3:

  1 # __author__ = 'cs'
  2 def dulk():
  3     print("%s is ...")
  4 class Dog(object):
  5     def __init__(self,name):
  6         self.name = name
  7     def eat(self):
  8         print("%s is eating..." %self.name)
  9 d = Dog("niuhanyang")
 10 choice = input(">>:").strip()    #輸入的是Dog這個類裏面的方法---->eat
 11 if hasattr(d,choice):            #判斷choice(輸入的)字符串在d(類)裏面是否存在
 12     #print(getattr(d,choice))      #獲取方法並打印
 13     getattr(d,choice)()           #獲取方法並執行
 14 else:
 15     setattr(d,choice,dulk)            #d.choice = dulk的內存地址
 16     fun = getattr(d,choice)
 17     fun()
View Code

3.異常處理                                                                                        

參考 http://www.cnblogs.com/wupeiqi/articles/5017742.html 

一、異常基礎

在編程過程當中爲了增長友好性,在程序出現bug時通常不會將錯誤信息顯示給用戶,而是現實一個提示的頁面,通俗來講就是不讓用戶看見大黃頁!!!

  1 try:
  2     pass
  3 except Exception,ex:
  4     pass

需求:將用戶輸入的兩個數字相加

  1 while True:
  2     num1 = raw_input('num1:')
  3     num2 = raw_input('num2:')
  4     try:
  5         num1 = int(num1)
  6         num2 = int(num2)
  7         result = num1 + num2
  8     except Exception, e:
  9         print '出現異常,信息以下:'
 10         print e
View Code

二、異常種類

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 致使你覺得正在訪問它
 13 ValueError 傳入一個調用者不指望的值,即便值的類型是正確的
經常使用異常
  1 ArithmeticError
  2 AssertionError
  3 AttributeError
  4 BaseException
  5 BufferError
  6 BytesWarning
  7 DeprecationWarning
  8 EnvironmentError
  9 EOFError
 10 Exception
 11 FloatingPointError
 12 FutureWarning
 13 GeneratorExit
 14 ImportError
 15 ImportWarning
 16 IndentationError
 17 IndexError
 18 IOError
 19 KeyboardInterrupt
 20 KeyError
 21 LookupError
 22 MemoryError
 23 NameError
 24 NotImplementedError
 25 OSError
 26 OverflowError
 27 PendingDeprecationWarning
 28 ReferenceError
 29 RuntimeError
 30 RuntimeWarning
 31 StandardError
 32 StopIteration
 33 SyntaxError
 34 SyntaxWarning
 35 SystemError
 36 SystemExit
 37 TabError
 38 TypeError
 39 UnboundLocalError
 40 UnicodeDecodeError
 41 UnicodeEncodeError
 42 UnicodeError
 43 UnicodeTranslateError
 44 UnicodeWarning
 45 UserWarning
 46 ValueError
 47 Warning
 48 ZeroDivisionError
 49 
 50 更多異常
更多異常
  1 dic = ["wupeiqi", 'alex']
  2 try:
  3     dic[10]
  4 except IndexError, e:
  5     print e
實例:IndexError
  1 dic = {'k1':'v1'}
  2 try:
  3     dic['k20']
  4 except KeyError, e:
  5     print e
實例:KeyError
  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except ValueError, e:
  5     print e
實例:ValueError

對於上述實例,異常類只能用來處理指定的異常狀況,若是非指定異常則沒法處理。

  1 # 未捕獲到異常,程序直接報錯
  2 
  3 s1 = 'hello'
  4 try:
  5     int(s1)
  6 except IndexError,e:
  7     print e
View Code

因此,寫程序時須要考慮到try代碼塊中可能出現的任意異常,能夠這樣寫:

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except IndexError,e:
  5     print e
  6 except KeyError,e:
  7     print e
  8 except ValueError,e:
  9     print e
View Code

萬能異常 在python的異常中,有一個萬能異常:Exception,他能夠捕獲任意異常,即:

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except Exception,e:
  5     print e
View Code

接下來你可能要問了,既然有這個萬能異常,其餘異常是否是就能夠忽略了!

答:固然不是,對於特殊處理或提醒的異常須要先定義,最後定義Exception來確保程序正常運行。

  1 s1 = 'hello'
  2 try:
  3     int(s1)
  4 except KeyError,e:
  5     print '鍵錯誤'
  6 except IndexError,e:
  7     print '索引錯誤'
  8 except Exception, e:
  9     print '錯誤'
View Code

三、異常其餘結構

  1 try:
  2     # 主代碼塊
  3     pass
  4 except KeyError,e:
  5     # 異常時,執行該塊
  6     pass
  7 else:
  8     # 主代碼塊執行完,執行該塊
  9     pass
 10 finally:
 11     # 不管異常與否,最終執行該塊
 12     pass
View Code

四、主動觸發異常

  1 try:
  2     raise Exception('錯誤了。。。')
  3 except Exception,e:
  4     print e
View Code

五、自定義異常

  1 class WupeiqiException(Exception):
  2 
  3     def __init__(self, msg):
  4         self.message = msg
  5 
  6     def __str__(self):
  7         return self.message
  8 
  9 try:
 10     raise WupeiqiException('個人異常')
 11 except WupeiqiException,e:
 12     print e
View Code

六、斷言

  1 # assert 條件
  2 
  3 assert 1 == 1
  4 
  5 assert 1 == 2
View Code

4.Socket網絡編程開發基礎                                                                

參考:http://www.cnblogs.com/wupeiqi/articles/5040823.html

socket一般也稱做"套接字",用於描述IP地址和端口,是一個通訊鏈的句柄,應用程序一般經過"套接字"向網絡發出請求或者應答網絡請求。

socket起源於Unix,而Unix/Linux基本哲學之一就是「一切皆文件」,對於文件用【打開】【讀寫】【關閉】模式來操做。socket就是該模式的一個實現,socket便是一種特殊的文件,一些socket函數就是對其進行的操做(讀/寫IO、打開、關閉)

socket和file的區別:

  • file模塊是針對某個指定文件進行【打開】【讀寫】【關閉】
  • socket模塊是針對 服務器端 和 客戶端Socket 進行【打開】【讀寫】【關閉】

socket server:

  1 #-*-coding:utf-8-*-
  2 #服務器端
  3 
  4 import socket
  5 server = socket.socket()
  6 server.bind(('localhost',6969)) #綁定要監聽端口
  7 server.listen(5) #監聽
  8 
  9 print("我要開始等電話了")
 10 while True:
 11     conn, addr = server.accept()  # 等電話打進來
 12     # conn就是客戶端連過來而在服務器端爲其生成的一個鏈接實例
 13     print(conn, addr)
 14     print("電話來了")
 15     count = 0
 16     while True:
 17         data = conn.recv(1024)
 18         print("recv:",data)
 19         if not data:
 20             print("client has lost...")
 21             break
 22         conn.send(data.upper())
 23         count+=1
 24         if count >10:break
 25 
 26 server.close()

socket client:

  1 #客戶端
  2 import socket
  3 
  4 client = socket.socket() #聲明socket類型,同時生成socket鏈接對象
  5 client.connect(('localhost',6969))
  6 
  7 while True:
  8     msg = input(">>:").strip()
  9     if len(msg) == 0:continue
 10     client.send(msg.encode("utf-8"))
 11     data = client.recv(10240)
 12     print("recv:",data.decode())
 13 
 14 client.close()

WEB服務應用:

  1 #!/usr/bin/env python
  2 #coding:utf-8
  3 import socket
  4 
  5 def handle_request(client):
  6     buf = client.recv(1024)
  7     client.send("HTTP/1.1 200 OK\r\n\r\n")
  8     client.send("Hello, World")
  9 
 10 def main():
 11     sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
 12     sock.bind(('localhost',8080))
 13     sock.listen(5)
 14 
 15     while True:
 16         connection, address = sock.accept()
 17         handle_request(connection)
 18         connection.close()
 19 
 20 if __name__ == '__main__':
 21   main()

更多功能

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 ,則系統就會根據地址格式和套接類別,自動選擇一個合適的協議

  1 import socket
  2 ip_port = ('127.0.0.1',9999)
  3 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
  4 sk.bind(ip_port)
  5 
  6 while True:
  7     data = sk.recv(1024)
  8     print data
  9 
 10 
 11 
 12 
 13 import socket
 14 ip_port = ('127.0.0.1',9999)
 15 
 16 sk = socket.socket(socket.AF_INET,socket.SOCK_DGRAM,0)
 17 while True:
 18     inp = raw_input('數據:').strip()
 19     if inp == 'exit':
 20         break
 21     sk.sendto(inp,ip_port)
 22 
 23 sk.close()
 24 
UDP Demo

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,失敗則拋出異常。

      內部經過遞歸調用send,將全部內容發送出去。

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()

  套接字的文件描述符

相關文章
相關標籤/搜索