Python之路-python(面向對象進階)


一、面向對象高級語法部分

  1、靜態方法、類方法、屬性方法

  2、類的特殊方法

  3、反射

二、異常處理

三、Socket開發基礎

 

一、面向對象高級語法部分

  靜態方法(@staticmethod

  定義:只是名義上歸類管理,實際上在在靜態方法里面訪問不了類或實例中的屬性

  

1 class Dog(object):
2     def __init__(self,name):
3         self.name = name
4 
5     @staticmethod
6     def eat(x,s):
7         print("%s is eating %s"%(x,s))
8 Dog.eat("df","fdasf")
9 》》》df is eating fdasf

  類方法(@classmethod

  定義:類方法只能訪問類變量,不能訪問實例變量

 1 class Dog(object):
 2     name = "444"
 3     def __init__(self,name):
 4         self.name = name
 5 
 6     @classmethod
 7     def eat(self):
 8         print("%s is eating"%(self.name))
 9 
10 d = Dog("zhangsan")
11 d.eat()
12 》》》444 is eating

  屬性方法(@property

  定義:把一個方法變成一個靜態屬性

 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name = name
 4 
 5     @property
 6     def eat(self):
 7         print(" %s is eating" %self.name)
 8 
 9 d = Dog("zhangsan")
10 d.eat()
11 》》》TypeError: 'NoneType' object is not callable
 1 正確的調用方法
 2 class Dog(object):
 3     def __init__(self,name):
 4         self.name = name
 5 
 6     @property
 7     def eat(self):
 8         print(" %s is eating" %self.name)
 9 
10 d = Dog("zhangsan")
11 d.eat#eat后面不加()

  類的特殊成員和方法

  1、__doc__,打印類的描述信息

  

 1 class Dog(object):
 2     '''
 3     這里是描述信息
 4     '''
 5     def __init__(self,name):
 6         self.name = name
 7 
 8     def eat(self):
 9         print(" %s is eating" %self.name)
10 
11 print(Dog.__doc__)
12 >>>這里是描述信息

  2、__module__ 和  __class__ 

 

1 class Dog(object):
2     def __init__(self):
3         self.name = "zhangsan"
1 from  test1 import Dog
2 obj = Dog()
3 print(obj.__module__)
4 print(obj.__class__)
5 >>>test1
6 >>><class 'test1.Dog'>

  反射:

 

 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name = name
 4     def eat(self):
 5         print("%s eating..."%self.name)
 6 
 7 d = Dog("zhangsan")
 8 choice = input("請輸入方法:")
 9 print(hasattr(d,choice))
10 #用戶輸入,如果有對應的方法,就會返回True,否則False

 

 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name = name
 4     def eat(self):
 5         print("%s eating..."%self.name)
 6 
 7 d = Dog("zhangsan")
 8 choice = input("請輸入方法:")
 9 if hasattr(d,choice):
10     func = getattr(d,choice)
11     func()#這里建議這么寫,可能后期要傳東西進去
12 else:
13     print("沒有該方法")
 1 class Dog(object):
 2     def __init__(self,name):
 3         self.name = name
 4     def eat(self,food):
 5         print("%s eating..."%self.name,food)
 6 
 7 d = Dog("zhangsan")
 8 choice = input("請輸入方法:")
 9 if hasattr(d,choice):
10     func = getattr(d,choice)
11     func("包子")#這里建議這么寫,可能后期要傳東西進去
12 else:
13     print("沒有該方法")
14 >>>請輸入方法:eat
15 >>>zhangsan eating... 包子
1 hasattr:判斷一個對象里面有沒有一個方法
2 getattr:打開一個對象對應的方法
3 setattr:建立一個方法,或者實例屬性
4 delattr:刪除一個方法,或者實例屬性
#setattr
def bulk(self):
    print("%s 叫。。。。"%self.name)

class Dog(object):
    def __init__(self,name):
        self.name = name
    def eat(self,food):
        print("%s eating..."%self.name,food)

d = Dog("zhangsan")
choice = input("請輸入方法:")
if hasattr(d,choice):
    func = getattr(d,choice)
    func("包子")#這里建議這么寫,可能后期要傳東西進去
else:
    setattr(d,choice,bulk)
    d.talk(d)
>>>請輸入方法:talk
>>>zhangsan 叫。。。。
 1 def bulk(self):
 2     print("%s 叫。。。。"%self.name)
 3 
 4 class Dog(object):
 5     def __init__(self,name):
 6         self.name = name
 7     def eat(self,food):
 8         print("%s eating..."%self.name,food)
 9 
10 d = Dog("zhangsan")
11 choice = input("請輸入方法:")
12 if hasattr(d,choice):
13     # func = getattr(d,choice)
14     # func("包子")#這里建議這么寫,可能后期要傳東西進去
15     delattr(d,choice)
16 else:
17     setattr(d,choice,bulk)
18     d.talk(d)
19 print(d.name)

 

 1 def bulk(self):
 2     print("%s 叫。。。。"%self.name)
 3 
 4 class Dog(object):
 5     def __init__(self,name):
 6         self.name = name
 7     def eat(self,food):
 8         print("%s eating..."%self.name,food)
 9 
10 d = Dog("zhangsan")
11 choice = input("請輸入方法:")
12 if hasattr(d,choice):
13     func = getattr(d,choice)
14     func("包子")#這里建議這么寫,可能后期要傳東西進去
15 else:
16     setattr(d,choice,bulk)
17     func = getattr(d,choice)
18     func(d)
19 >>>這里實現了一個通過用戶輸入的字符串反射到類里面的屬性

  二、異常處理

  常用異常

  

AttributeError 試圖訪問一個對象沒有的樹形,比如foo.x,但是foo沒有屬性x
IOError 輸入/輸出異常;基本上是無法打開文件
ImportError 無法引入模塊或包;基本上是路徑問題或名稱錯誤
IndentationError 語法錯誤(的子類) ;代碼沒有正確對齊
IndexError 下標索引超出序列邊界,比如當x只有三個元素,卻試圖訪問x[5]
KeyError 試圖訪問字典里不存在的鍵
KeyboardInterrupt Ctrl+C被按下
NameError 使用一個還未被賦予對象的變量
SyntaxError Python代碼非法,代碼不能編譯(個人認為這是語法錯誤,寫錯了)
TypeError 傳入對象類型與要求的不符合
UnboundLocalError 試圖訪問一個還未被設置的局部變量,基本上是由於另有一個同名的全局變量,
導致你以為正在訪問它
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
#根據可能出現的錯誤,可以這么寫
s1 = 'hello'
try:
    int(s1)
except IndexError as e:
    print(e)
except KeyError as e:
    print(e)
except ValueError as e:
    print(e)

  萬能異常:

s1 = 'hello'
try:
    int(s1)
except Exception as e:#一般建議后面做
    print(e)

  異常的其它結構:

try:
    # 主代碼塊
    pass
except KeyError,e:
    # 異常時,執行該塊
    pass
else:
    # 主代碼塊執行完,執行該塊
    pass
finally:
    # 無論異常與否,最終執行該塊
    pass
#主動觸發異常
try:
    raise Exception('錯誤了。。。')
except Exception as e:
    print(e)

  自定義異常:

#自定義錯誤基本寫法
class Lei_Error(Exception):
    def __init__(self,msg):
        self.msg = msg

try:
    raise Lei_Error("自定義錯誤")
except Lei_Error as e:
    print(e)
>>>自定義錯誤

  Socket:

 

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

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

socket和file的區別:

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

 

更多功能

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

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

  套接字的文件描述符

 

 

 1 #socket服務端
 2 #!/usr/bin/env python
 3 import  socket,os
 4 server = socket.socket()
 5 server.bind(("localhost",6969))#綁定要監聽的端口
 6 server.listen()#監聽
 7 print("我在等電話")
 8 while True:
 9     conn,addr = server.accept()#等待請求
10     print(conn,addr)
11     #conn就是客戶端連過來而在服務器端為其生成的一個連接實例
12     print("電話來了")
13     while True:
14         data = conn.recv(4096)
15         print("recv:",data)
16         if not data:
17             break
18         res =  os.popen(data).read()
19         conn.send(res)
20     server.close()
#socket客戶端
import  socket

client = socket.socket()#聲明socket類型,同時生成socket連接對象
client.connect(('localhost',6969))#定義連接ip和port
while True:
    msg = input(">>>:")
    if len(msg)== 0:continue
    client.send(msg.encode("utf8"))
    data = client.recv(4096)
    print(data.decode())
client.close()

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM