說反射之前先介紹一下__import__方法,這個和import導入模塊的另一種方式
1. import commons 2. __import__('commons')
如果是多層導入:
1. from list.text import commons 2. __import__(' list.text.commons',fromlist=True) #如果不加上fromlist=True,只會導入list目錄
反射有即想到4個內置函數分別為:getattr、hasattr、setattr、delattr 獲取成員、檢查成員、設置成員、刪除成員下面逐一介紹先看例子:
class Foo(object): def __init__(self): self.name = 'abc' def func(self): return 'ok' obj = Foo() #獲取成員 ret = getattr(obj, 'func')#獲取的是個對象 r = ret() print(r) #檢查成員 ret = hasattr(obj,'func')#因為有func方法所以返回True print(ret) #設置成員 print(obj.name) #設置之前為:abc ret = setattr(obj,'name',19) print(obj.name) #設置之後為:19 #刪除成員 print(obj.name) #abc delattr(obj,'name') print(obj.name) #報錯
對於反射小節:
1.根據字符串的形式導入模塊。 2.根據字符串的形式去對象(某個模塊)中操作其成員
實例:基於反射實現類Web框架的路由系統
實現思路:規定用戶輸入格式 模塊名/函數名 通過__import__的形式導入模塊並通過 hasattr和getattr 檢查並獲取函數返回值。
面向對象簡稱OOP,面向對象的程序設計把計算機程序視為一組對象的集合,而每個對象都可以接收其他對象發過來的消息,並處理這些消息,計算機程序的執行就是一系列消息在各個對象之間傳遞。
語法格式見下圖:
關鍵字class 和函數def 是一樣的。類名通常是大寫開頭的單詞,定義號類後就可以創建實例如上圖的類加()就相當於創建一個類的實例obj
類的三大特性:封裝、繼承、多態
1、封裝
面向對象編程的一個重要特點就是數據封裝。例如:
class Foo: def fetch(self): print(self.beckend) #self 直接在對象裡面取值 obj = Foo() obj.beckend = 'www.baidu.com' #把beckend封裝在對象裡面 obj.fetch()非主流的用法
class Foo : '''構造方法''' def __init__(self,bk): self.backend = bk # 把obj對象的參數封裝在 init 方法裡 def fetch(self): print(self.backend) def add(self): print(self.backend) obj = Foo('www.xxx.com') obj.fetch() obj.add()主流用法
通過代碼我們看到__init__:稱之為構造方法,需要注意__init__的第一個參數永遠是self,表示的實例本身
封裝的意義:當同一類型的方法具有相同的參數時,可以直接封裝到對象裡減少代碼量。
使用場景把類當作模版,創建多個對象並且對象內封裝的數據可以不同。
2、繼承
當我們定義一個class的時候,可以從某個現有的class繼承,新的class稱為子類(Subclass),而被繼承的class稱為基類、父類或超類(Base class、Super class),有幾點要注意:
例如下面的例子:
class Animals: def chi(self): print(self.Name + ' 吃') def he(self): print(self.Name + ' 喝') class Dog(Animals): def __init__(self,name): self.Name = name def jiao(self): print(self.Name + ' 叫') xxoo =Dog('某某某') xxoo.chi() xxoo.he() xxoo.jiao()繼承實例
class Animals: def chi(self): print(self.Name +' 吃') def he(self): print(self.Name + ' 喝') class Uncle: def du(self): print(self.Name + ' 賭') class Dog(Animals,Uncle): def __init__(self,name): self.Name = name xxoo = Dog('某某某') xxoo.chi() xxoo.du()多繼承
關於繼承順序需要注意例如 E繼承(C,D) -->C繼承(A)-->D繼承(B) 如下圖(python3):
class A: def f1(self): print('A') class B: def f(self): print('B') class C(A): def f(self): print('C') class D(B): def f1(self): print('D') class E(C,D): def f(self): print('E') aa = E() aa.f1()類的查找順序
第二種查找順序:E繼承(C,D)-->C繼承(A),D繼承(B)-->A和B都繼承(Boos) ,查找順序如下:
class Boos: def f1(self): print('Boos') class A(Boos): def f(self): print('A') class B(Boos): def f(self): print('B') class C(A): def f(self): print('C') class D(B): def f1(self): print('D') class E(C,D): def f(self): print('E') aa = E() aa.f1()查找順序
3、多態
即多種形態....
補充:
關於繼承如何執行父類的構造方法那?有兩種方法如下代碼:
class Annimal: def __init__(self): print('Annimal的構造方法') self.ty = '動物' class Cat(Annimal): def __init__(self): print('Cat的構造方法') self.n = '貓' super(Cat, self).__init__() #推薦用這種 # Annimal.__init__(self) #第二種方式 c = Cat()執行父類構造方法
查找源碼的過程(self.xxxx(),從底層開始找)
分別有靜態字段、靜態方法、類方法、特性、普通字段、普通方法、
class Provice: #靜態字段 country ='China' def __init__(self,name): #普通字段 self.name = name #普通方法 def show(self): print('show') @staticmethod #靜態方法 def xo(arg): print('xo') print(arg) @classmethod #類方法,必須要有個cls參數:自動傳入類名 def xxoo(cls): print('xxoo',cls) def start(self): print('start') @property #特性 def end(self): print('end') @end.setter def end(self,values): print(values) self.name = values #也可以更改內存裡的值 Provice.country #類訪問靜態字段 Provice.xo('alex') #類訪問靜態方法 Provice.xxoo() #訪問類方法 #獲取特性值 obj = Provice('alex') obj.end #設置特性值 obj1= Provice('alex') obj1.end='123' print(obj1.name) #普通方法 obj1= Provice('alex') obj1.show() #普通字段 obj1= Provice('alex') print(obj1.name)
成員小節:
通過類訪問的有:靜態字段、靜態方法、類方法
通過對象訪問:普通字段、普通方法 、特性
靜態字段:存在類中 ,靜態字段存在的意:把對象裡面重復的數據只在類裡保存一份 靜態方法 :沒有self 可以傳參數,調用的時候也需要傳入參數 ,存在的意義:不需要創建對象,就可以訪問此方法 ,為類而生 類方法:必須要有個cls參數:自動傳入類名 特性 對象調用 、不能加參數,執行不用加括號 普通字段,存放在對象中 普通方法 存在的意義:普通方法如果要想被調用就需要創建self ,為對象而生各成員存在的意義
公有成員:任何地方都能訪問
私有成員:只有在類的內部才能訪問,定義方式為命名時,前兩個字符為下劃線,如 "__test"
class Person(object): country = 'China' #靜態字段,屬於公有成員 __planet = 'Earth' #靜態字段,屬於私有成員 def __init__(self,name): print 'Person build self.name' self.name = name def say(self): print 'The planet is %s'%Person.__planet #在類的內部訪問私有靜態字段 p1 = Person('Nothing') p1.say() print p1.country #訪問公有靜態字段 print p1.__planet #訪問私有靜態字段 #執行結果: Person build self.name The planet is Earth #在類的內部可以訪問 print p1.__planet China #外部可以訪問公有靜態字段 AttributeError: 'Person' object has no attribute '__planet' #外部無法訪問私有靜態字段
小節:私有成員只能在類內部使用,其他的都不能使用包括繼承的子類
類的特殊成員:
__doc__ 表示類的描述信息 __module__ 表示當前操作的對象在那個模塊 __class__ 表示當前操作的對象的類是什麼 __init__ 構造方法,通過類創建對象時,自動觸發執行 __call__ 對象後面加括號,觸發執行。 __dict__ 類或對象中的所有成員 __str__ 如果一個類中定義了__str__方法,那麼在打印 對象 時,默認輸出該方法的返回值。 __init__ 構造方法,通過類創建對象時,自動觸發執行 __setitem__,__getitem__,__delitem__ 用於索引操作,如字典。分別表示獲取、設置、刪除數據
異常即是一個事件,該事件會在程序執行過程中發生,影響了程序的正常執行。
一般情況下,在Python無法正常處理程序時就會發生一個異常。
異常是Python對象,表示一個錯誤。
當Python腳本發生異常時我們需要捕獲處理它,否則程序會終止執行。
語法:
try: <語句> #運行別的代碼 except <名字>: <語句> #如果在try部份引發了'name'異常 except <名字>,<數據>: <語句> #如果引發了'name'異常,獲得附加的數據 else: <語句> #如果沒有異常發生 finally: xxxx
標准的異常有:
BaseException 所有異常的基類 SystemExit 解釋器請求退出 KeyboardInterrupt 用戶中斷執行(通常是輸入^C) Exception 常規錯誤的基類 StopIteration 迭代器沒有更多的值 GeneratorExit 生成器(generator)發生異常來通知退出 StandardError 所有的內建標准異常的基類 ArithmeticError 所有數值計算錯誤的基類 FloatingPointError 浮點計算錯誤 OverflowError 數值運算超出最大限制 ZeroDivisionError 除(或取模)零 (所有數據類型) AssertionError 斷言語句失敗 AttributeError 對象沒有這個屬性 EOFError 沒有內建輸入,到達EOF 標記 EnvironmentError 操作系統錯誤的基類 IOError 輸入/輸出操作失敗 OSError 操作系統錯誤 WindowsError 系統調用失敗 ImportError 導入模塊/對象失敗 LookupError 無效數據查詢的基類 IndexError 序列中沒有此索引(index) KeyError 映射中沒有這個鍵 MemoryError 內存溢出錯誤(對於Python 解釋器不是致命的) NameError 未聲明/初始化對象 (沒有屬性) UnboundLocalError 訪問未初始化的本地變量 ReferenceError 弱引用(Weak reference)試圖訪問已經垃圾回收了的對象 RuntimeError 一般的運行時錯誤 NotImplementedError 尚未實現的方法 SyntaxError Python 語法錯誤 IndentationError 縮進錯誤 TabError Tab 和空格混用 SystemError 一般的解釋器系統錯誤 TypeError 對類型無效的操作 ValueError 傳入無效的參數 UnicodeError Unicode 相關的錯誤 UnicodeDecodeError Unicode 解碼時的錯誤 UnicodeEncodeError Unicode 編碼時錯誤 UnicodeTranslateError Unicode 轉換時錯誤 Warning 警告的基類 DeprecationWarning 關於被棄用的特征的警告 FutureWarning 關於構造將來語義會有改變的警告 OverflowWarning 舊的關於自動提升為長整型(long)的警告 PendingDeprecationWarning 關於特性將會被廢棄的警告 RuntimeWarning 可疑的運行時行為(runtime behavior)的警告 SyntaxWarning 可疑的語法的警告 UserWarning 用戶代碼生成的警告