Python-Day7 面向對象進階/異常處理/Socket

1、面向對象高級語法部分python

1.靜態方法

    經過@staticmethod裝飾器便可把其裝飾的方法變爲一個靜態方法,什麼是靜態方法呢?其實不難理解,普通的方法,能夠在實例化後直接調用,而且在方法裏能夠經過self.調用實例變量或類變量,但靜態方法是不能夠訪問實例變量或類變量的,一個不能訪問實例變量和類變量的方法,其實至關於跟類自己已經沒什麼關係了,它與類惟一的關聯就是須要經過類名來調用這個方法。程序員

class Dog(object): def __init__(self,name): self.name = name @staticmethod #把eat方法變爲靜態方法
    def eat(self): print("%s is eating" % self.name) d = Dog("ha") d.eat()

上面的調用會出如下錯誤,說是eat須要一個self參數,但調用時卻沒有傳遞,沒錯,當eat變成靜態方法後,再經過實例調用時就不會自動把實例自己看成一個參數傳給self了。編程

<span style="color: #ff0000;">Traceback (most recent call last): File "/Users/jieli/PycharmProjects/python基礎/自動化day7面向對象高級/靜態方法.py", line 17, in <module> d.eat() TypeError: eat() missing 1 required positional argument: 'self'
</span>

想讓上面的代碼能夠正常工做有兩種辦法ide

1. 調用時主動傳遞實例自己給eat方法,即d.eat(d) 函數

2. 在eat方法中去掉self參數,但這也意味着,在eat中不能經過self.調用實例中的其它變量了ui

class Dog(object): def __init__(self,name): self.name = name @staticmethod def eat(): print(" is eating") d = Dog("ha") d.eat()

2.類方法

    類方法經過@classmethod裝飾器實現,類方法和普通方法的區別是, 類方法只能訪問類變量,不能訪問實例變量。spa

class Dog(object): def __init__(self,name): self.name = name @classmethod def eat(self): print("%s is eating" % self.name) d = Dog("ha") d.eat()

執行報錯以下,說Dog沒有name屬性,由於name是個實例變量,類方法是不能訪問實例變量的code

Traceback (most recent call last): File "/Users/jieli/PycharmProjects/python基礎/自動化day7面向對象高級/類方法.py", line 16, in <module> d.eat() File "/Users/jieli/PycharmProjects/python基礎/自動化day7面向對象高級/類方法.py", line 11, in eat print("%s is eating" % self.name) AttributeError: type object 'Dog' has no attribute 'name'

此時能夠定義一個類變量,也叫name,看下執行效果對象

class Dog(object): name = "我是類變量"
    def __init__(self,name): self.name = name @classmethod def eat(self): print("%s is eating" % self.name) d = Dog("ha") d.eat() #執行結果
 我是類變量 is eating

3.屬性方法

屬性方法的做用就是經過@property把一個方法變成一個靜態屬性blog

class Dog(object): def __init__(self,name): self.name = name @property def eat(self): print(" %s is eating" %self.name) d = Dog("ha") d.eat()

調用會出如下錯誤, 說NoneType is not callable, 由於eat此時已經變成一個靜態屬性了, 不是方法了, 想調用已經不須要加()號了,直接d.eat就能夠了

Traceback (most recent call last): ChenRonghua is eating File "/Users/jieli/PycharmProjects/python基礎/自動化day7面向對象高級/屬性方法.py", line 16, in <module> d.eat() TypeError: 'NoneType' object is not callable

正常調用以下

d = Dog("ha") d.eat 輸出 ha is eating

4.類的特殊成員方法

 __doc__  表示類的描述信息

class Foo: """ 描述類信息,這是用於看片的神奇 """
 
    def func(self): pass
 
print Foo.__doc__
#輸出:類的描述信息

__module__ 和  __class__

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

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

class C: def __init__(self): self.name = 'wupeiqi'
from lib.aa import C obj = C() print obj.__module__  # 輸出 lib.aa,即:輸出模塊
print obj.__class__      # 輸出 lib.aa.C,即:輸出類

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

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

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

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


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

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

class Province: country = 'China'
 
    def __init__(self, name, count): self.name = name self.count = count def func(self, *args, **kwargs): print 'func'
 
# 獲取類的成員,即:靜態字段、方法、
print Province.__dict__
# 輸出:{'country': 'China', '__module__': '__main__', 'func': <function func at 0x10be30f50>, '__init__': <function __init__ at 0x10be30ed8>, '__doc__': None}
 obj1 = Province('HeBei',10000) print obj1.__dict__
# 獲取 對象obj1 的成員 # 輸出:{'count': 10000, 'name': 'HeBei'}
 obj2 = Province('HeNan', 3888) print obj2.__dict__
# 獲取 對象obj1 的成員 # 輸出:{'count': 3888, 'name': 'HeNan'}

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

class Foo: def __str__(self): return 'alex li' obj = Foo() print obj # 輸出:alex li

__getitem__、__setitem__、__delitem__

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

class Foo(object): def __getitem__(self, key): print('__getitem__',key) def __setitem__(self, key, value): print('__setitem__',key,value) def __delitem__(self, key): print('__delitem__',key) obj = Foo() result = obj['k1']      # 自動觸發執行 __getitem__
obj['k2'] = 'alex'   # 自動觸發執行 __setitem__
del obj['k1']   

__new__ \ __metaclass__

class Foo(object): def __init__(self,name): self.name = name f = Foo("alex")

上述代碼中,obj 是經過 Foo 類實例化的對象,其實,不只 obj 是一個對象,Foo類自己也是一個對象,由於在Python中一切事物都是對象

若是按照一切事物都是對象的理論:obj對象是經過執行Foo類的構造方法建立,那麼Foo類對象應該也是經過執行某個類的 構造方法 建立。

print type(f) # 輸出:<class '__main__.Foo'> 表示,obj 對象由Foo類建立
print type(Foo) # 輸出:<type 'type'> 表示,Foo類對象由 type 類建立

因此,f對象是Foo類的一個實例Foo類對象是 type 類的一個實例,即:Foo類對象 是經過type類的構造方法建立。

那麼,建立類就能夠有兩種方式:

a). 普通方式 

class Foo(object): def func(self): print 'hello alex'

b). 特殊方式

def func(self): print 'hello wupeiqi' Foo = type('Foo',(object,), {'func': func}) #type第一個參數:類名 #type第二個參數:當前類的基類 #type第三個參數:類的成員
def func(self): print("hello %s"%self.name) def __init__(self,name,age): self.name = name self.age = age Foo = type('Foo',(object,),{'func':func,'__init__':__init__}) f = Foo("jack",22) f.func()

類 是由 type 類實例化產生

那麼問題來了,類默認是由 type 類實例化產生,type類中如何實現的建立類?類又是如何建立對象?

答:類中有一個屬性 __metaclass__,其用來表示該類由 誰 來實例化建立,因此,咱們能夠爲 __metaclass__ 設置一個type類的派生類,從而查看 類 建立的過程。

#_*_coding:utf-8_*_
__author__ = 'Alex Li'
 
 
class MyType(type): 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---") obj = self.__new__(self, *args, **kwargs) self.__init__(obj, *args, **kwargs) 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) # 第一階段:解釋器從上到下執行代碼建立Foo類 # 第二階段:經過Foo類建立obj對象
obj = Foo("Alex")

5、反射

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

① hasattr(obj,str) 判斷一個對象obj裏是否有對應的str字符串的方法

② getattr(obj,str) 根據字符串去獲取obj對象裏的對應的方法的內存地址

#hasattr、getattr
 
class Foo(object): def __init__(self,name): self.name = name def func(self): print("func",self.name) obj = Foo("alex") str = "func"
 
print(hasattr(obj,str))   # 檢查是否含有成員 有沒有obj.str屬性
 
if hasattr(obj,str): getattr(obj,str)() #getattr(obj,str) = obj.str
 
# True # func alex

③ setattr(obj,'y','z')  obj.y = z

#setattr
 
def bulk(self): print("%s is yelling"%self.name) class Foo(object): def __init__(self,name): self.name = name def func(self): print("func",self.name) obj = Foo("alex") str = "talk"
 
print(hasattr(obj,str))   # 檢查是否含有成員 有沒有obj.str屬性
 
if hasattr(obj,str): getattr(obj,str)() # getattr(obj,str) = obj.str
 
else: setattr(obj,str,bulk) # setattr(obj,str,bulk 至關於 obj.str = bulk
 getattr(obj,str)(obj) # False # alex is yelling

④ delattr(obj,str) 刪除obj.str

#delattr
 
class Foo(object): def __init__(self,name): self.name = name def func(self): print("func",self.name) obj = Foo("alex") str = "name"
 
if hasattr(obj,str): delattr(obj,str) # 刪除屬性obj.str
 
print(obj.name) # Traceback (most recent call last): # File "C:/Users/L/PycharmProjects/s14/preview/Day7/main.py", line 40, in <module> # print(obj.name) # AttributeError: 'Foo' object has no attribute 'name'

2、異常處理

一、異常基礎

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

#異常處理
 list = ["hello","world"] try: list[3] except IndexError as e: print("IndexError",e) # IndexError list index out of range

上面程序表示try裏面的代碼若是出現IndexError這種錯誤,則執行except下面的代碼,不會把錯誤信息顯示給用戶,程序也不會中止;目前只能處理IndexError這一種異常,想處理多種異常還能夠這麼寫:

#多種異常處理
 list = ["hello","world"] try: list[3] except IndexError as e: print("IndexError",e) except KeyError as e: print("KeyError", e) except ValueError as e: print("ValueError",e) # IndexError list index out of range

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

#萬能異常處理
 list = ["hello","world"] try: list[3] except Exception as e: print("Error",e) #Error list index out of range
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
所有異常

二、異常的其餘結構

#異常的其餘結構
 
try: # 主代碼塊
    pass
except KeyError as e: # 異常時,執行該塊
    pass
else: # 主代碼塊執行完,執行該塊
    pass
finally: # 不管異常與否,最終執行該塊
    pass

三、自定義異常 

#主動觸發異常
 
try: raise Exception('錯誤了。。。') except Exception as e: print(e) #錯誤了。。。
#自定義異常
 
class Diyexception(Exception): def __init__(self, msg): self.message = msg def __str__(self): return self.message error = Diyexception("報錯了....") try: raise error except Diyexception as e: print(e) #報錯了....
相關文章
相關標籤/搜索