Python自動化開發學習的第七週---面向對象編程進階

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

1.多重繼承  經典類vs新式類 

class P1:
    def foo(self):
        print("P1-foo")

class P2:
    def foo(self):
        print("P2-foo")
    def bar(self):
        print("P2-bar")

class C1(P1,P2):
    pass
class C2(P1,P2):
    def bar(self):
        print("C2-bar")

class GC(C1,C2):
    pass

經典類,經過在交互式的解釋器中執行上面的聲明,咱們能夠驗證經典類使用的解釋順序,深度優先,從左至右。html

>>>gc = GC()
>>>gc.foo()  #GC==>C1==>P1
P1-foo >>>gc.bar() #GC==>C1==>P1==>P2
P2-bar

新式類 咱們在類P1和P2的後面加上(object),就是新式類,從新執行下python

>>>gc = GC()
>>>gc.foo()  #GC==>C1==>C2==>P1
P1-foo
>>>gc.bar() #GC==>C1==>C2
C2-bar

新式類,經過在交互式的解釋器中執行上面的聲明,咱們能夠驗證經典類使用的解釋順序,廣度優先,從左至右。app

 

2.靜態方法、類方法、屬性方法

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

class Dog(object):

    #name="zhangsan"
    def __init__(self,name):
        self.name=name
        self.__food__=None

    @staticmethod #靜態方法,實際上脫離了類
    def eat(self):
        print("%s is eating %s"%("zhangsan","jiaozi"))


d=Dog("ZhangSan")
d.eat("baozi")

運行結果:
zhangsan is eating jiaozi

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

class Dog(object):

    #name="zhangsan"
    def __init__(self,name):
        self.name=name
        self.__food__=None


    @classmethod  # 類方法,只能訪問類變量,不能訪問實例變量
    def eat(self,food):
        print("%s is eating %s" % (self.name, food))



d=Dog("ZhangSan")
d.eat("baozi")

顯示報錯誤:
Traceback (most recent call last):
  File "E:/Ahappier/python/day10/靜態方法.py", line 31, in <module>
    d.eat("baozi")
  File "E:/Ahappier/python/day10/靜態方法.py", line 18, in eat
    print("%s is eating %s" % (self.name, food))
AttributeError: type object 'Dog' has no attribute 'name'

如今定義一個類變量叫name,看一下效果:spa

class Dog(object):

    name="zhangsan"
    def __init__(self,name):
        self.name=name
        self.__food__=None

    @classmethod  # 類方法,只能訪問類變量,不能訪問實例變量
    def eat(self,food):
        print("%s is eating %s" % (self.name, food))


d=Dog("ZhangSan")
d.eat("baozi")

運行結果:
zhangsan is eating baozi

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

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

d=Dog("ZhangSan")
d.eat("baozi")

顯示報錯:
ZhangSan is eating None
Traceback (most recent call last):
  File "E:/Ahappier/python/day10/靜態方法.py", line 29, in <module>
    d.eat("baozi")
TypeError: 'NoneType' object is not callable

把調用方法改變下:
d=Dog("ZhangSan")
d.eat

顯示:
ZhangSan is eating None

把一個方法變成靜態屬性有什麼用處呢?既然要靜態屬性,那直接定義一個靜態屬性不就能夠嗎?之後你會不少場景不是簡單的定義靜態屬性就能夠的,好比,查看火車的當前狀態,是到達了,走了,晚點了~~等等code

3.類的特殊成員方法

3.1. __doc__  表示類的描述信息

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

運行結果:
 描述類信息,這是用於看片的神奇 

3.2. __module__ 和  __class__ 

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

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

1 class C:
2 
3     def __init__(self):
4         self.name = 'wupeiqi'
lib/aa.py
1 from lib.aa import C
2 
3 obj = C()
4 print obj.__module__  # 輸出 lib.aa,即:輸出模塊
5 print obj.__class__      # 輸出 lib.aa.C,即:輸出類
index.py= 

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

3.4.__del__

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

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

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

class Foo:
 
    def __init__(self):
        pass
     
    def __call__(self, *args, **kwargs):
 
        print '__call__'
 
 
obj = Foo() # 執行 __init__
obj()       # 執行 __call__

3.6. __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'}

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

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

3.8.__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']   

3.9. __new__ \ __metaclass__

http://www.cnblogs.com/alex3714/articles/5213184.html

4.反射

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

class Foo(object):
 
    def __init__(self):
        self.name = 'wupeiqi'
 
    def func(self):
        return 'func'
 
obj = Foo()
 
# #### 檢查是否含有成員 ####
#hasattr(object,name)判斷object中有沒有一個name的字符串對應的方法和屬性 hasattr(obj, 'name') hasattr(obj, 'func') # #### 獲取成員 ####
#getattr(object,name,default=None) getattr(obj, 'name') getattr(obj, 'func') # #### 設置成員 ####
#setattr(x,y,v)==(x.y=v) setattr(obj, 'age', 18) setattr(obj, 'show', lambda num: num + 1) # #### 刪除成員 ####
#delattr(x,y)==del x.y delattr(obj, 'name') delattr(obj, 'func')

5.動態模塊導入

lib = __import__("lib.aa")
print(lib)
obj = lib.aa.C().name
print(obj)


import importlib
aa = importlib.import_module("lib.aa")
print(aa)
print(aa.C().name)
View Code

 

 運行結果是:

<module 'lib' from 'C:\\python\\day10\\lib\\__init__.py'>
alex
<module 'lib.aa' from 'C:\\python\\day10\\lib\\aa.py'>
alex

 

 

2、異常處理

1.python中的錯誤異常

你必定遇到過程序「崩潰」 或者因未解決的錯誤而終止的狀況。你會看到「traceback/跟蹤返回」的消息,以及隨後解釋器向你提供的信息,包括錯誤的名稱,緣由,以及發生錯誤的行號。無論你是經過python解釋器執行仍是標準的腳本執行,全部的錯誤都符合類似的格式,這提供了一個一致的錯誤接口。全部的錯誤,不管是語意上的仍是邏輯上的,都是因爲和python解釋器的不相容致使的,其後引起的異常。

2.檢測和處理異常

異常能夠經過try語句來檢測。任何在try語句塊的代碼都會被檢測,檢查有無異常發生

try 語句有兩種主要形式: try-except 和 try-finally . 這兩個語句是互斥的, 也就是說你 只 能 使 用 其 中 的 一 種 . 一 個 try 語 句 可 以 對 應 一 個 或 多 個 except 子 句 , 但 只 能 對 應 一 個 finally 子句, 或是一個 try-except-finally 複合語句. 你可使用 try-except 語句檢測和處理異常. 你也能夠添加一個可選的 else 子句處理沒 有探測到異常的時執行的代碼. 而 try-finally 只容許檢測異常並作一些必要的清除工做(不管 發生錯誤與否), 沒有任何異常處理設施. 正如你想像的,複合語句二者均可以作到. 

核心筆記: 忽略代碼, 繼續執行, 和向上移交 try 語句塊中異常發生點後的剩餘語句永遠不會到達(因此也永遠不會執行). 一旦一個異常被 引起, 就必須決定控制流下一步到達的位置. 剩餘代碼將被忽略, 解釋器將搜索處理器, 一旦找到, 就開始執行處理器中的代碼. 若是沒有找到合適的處理器, 那麼異常就向上移交給調用者去處理, 這意味着堆棧框架當即回 到以前的那個. 若是在上層調用者也沒找到對應處理器, 該異常會繼續被向上移交, 直到找到合適 處理器. 若是到達最頂層仍然沒有找到對應處理器, 那麼就認爲這個異常是未處理的, Python 解釋 器會顯示出跟蹤返回消息, 而後退出.

try:
    pass
except Exception,ex:
    pass

3.異常種類

 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 傳入一個調用者不指望的值,即便值的類型是正確的
14 
15 經常使用異常
經常使用異常
 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 更多異常
其餘異常

 

4.萬能異常

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

s1 = 'hello'
try:
    int(s1)
except Exception as e:
    print (e)

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

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

未完待續~~~

相關文章
相關標籤/搜索