程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> 更多編程語言 >> Python >> Python系列之反射、函數

Python系列之反射、函數

編輯:Python

一、反射

說反射之前先介紹一下__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. def Bar(self)  其中self 為形式參數 
  2. 和實例化對象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),有幾點要注意:

  1. 繼承要在子類加上父類的類名
  2. 子類和父類都有的方法,優先找子類的方法
  3. python裡面可以繼承多個類C#,java 不可以多繼承
  4. 如果繼承多個類,繼承順序為從左至右

 例如下面的例子:

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)

成員小節:

  1. 自己去訪問自己的成員,除了類中的方法
  2. 通過類訪問的有:靜態字段、靜態方法、類方法

  3. 通過對象訪問:普通字段、普通方法 、特性

靜態字段:存在類中 ,靜態字段存在的意:把對象裡面重復的數據只在類裡保存一份
靜態方法 :沒有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	用戶代碼生成的警告
  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved