python完全支持面向对象编程_python面向对象编程----009
本篇內(nèi)容:
1、反射
2、面向?qū)ο缶幊?/p>
3、面向?qū)ο笕筇匦?/p>
4、類成員
5、類成員修飾符
6、類的特殊成員
7、單例模式
反射
python中的反射功能是由以下四個內(nèi)置函數(shù)提供:hasattr、getattr、setattr、delattr,改四個函數(shù)分別用于對對象內(nèi)部執(zhí)行:檢查是否含有某成員、獲取成員、設(shè)置成員、刪除成員。
通過字符串的形式導(dǎo)入模塊
指定函數(shù)中執(zhí)行指定函數(shù)
1、getattr
通過字符串的形式去某個模塊中尋找東西
demo
2、hasattr
通過字符串的形式去某個模塊中判斷東西是否存在
demo
3、setattr
通過字符串的形式去某個模塊中設(shè)置東西
demo
4、delattr
demo
案例:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
'''
基于web框架實現(xiàn)路由功能
'''
url= str(input("請輸入URL:"))#輸入URL,先輸入模塊,后面加函數(shù)
target_moudle,target_func= url.split("/")# 用/把分割開,前面是模塊 后面是函數(shù)
moudle= __import__(target_moudle,fromlist=True)#導(dǎo)入模塊
if hasattr(moudle,target_func):#判斷模塊里有這個函數(shù)
target_func= getattr(moudle,target_func)#找到那個函數(shù)
ret= target_func()#執(zhí)行函數(shù)
print(ret)
else:#否則報錯
print("404")
反射類實例
面向?qū)ο缶幊?/p>
面向過程:根據(jù)業(yè)務(wù)邏輯從上到下寫壘代碼
函數(shù)式:將某功能代碼封裝到函數(shù)中,日后便無需重復(fù)編寫,僅調(diào)用函數(shù)即可
面向?qū)ο?#xff1a;對函數(shù)進(jìn)行分類和封裝,讓開發(fā)“更快更好更強(qiáng)...”
面向過程編程最易被初學(xué)者接受,其往往用一長段代碼來實現(xiàn)指定功能,開發(fā)過程中最常見的操作就是粘貼復(fù)制,即:將之前實現(xiàn)的代碼塊復(fù)制到現(xiàn)需功能處。
1、創(chuàng)建類和對象
面向?qū)ο缶幊淌且环N編程方式,此編程方式的落地需要使用 “類” 和 “對象” 來實現(xiàn),所以,面向?qū)ο缶幊唐鋵嵕褪菍?“類” 和 “對象” 的使用。
類就是一個模板,模板里可以包含多個函數(shù),函數(shù)里實現(xiàn)一些功能
對象則是根據(jù)模板創(chuàng)建的實例,通過實例對象可以執(zhí)行類中的函數(shù)
class是關(guān)鍵字,表示類
創(chuàng)建對象,類名稱后加括號即可
1
2
3
4
5
6
7
8
9
10
11
12
13
# 創(chuàng)建類
class Foo:
def Bar(self):
print 'Bar'
def Hello(self, name):
print 'i am %s' %name
# 根據(jù)類Foo創(chuàng)建對象obj
obj= Foo()
obj.Bar()#執(zhí)行Bar方法
obj.Hello('wupeiqi')#執(zhí)行Hello方法
一、封裝
封裝,顧名思義就是將內(nèi)容封裝到某個地方,以后再去調(diào)用被封裝在某處的內(nèi)容。所以,在使用面向?qū)ο蟮姆庋b特性時,需要:
將內(nèi)容封裝到某處
從某處調(diào)用被封裝的內(nèi)容
第一步:將內(nèi)容封裝到某處
demo
第二步:從某處調(diào)用被封裝的內(nèi)容調(diào)用被封裝的內(nèi)容時,有兩種情況:
通過對象直接調(diào)用
通過self間接調(diào)用
1、通過對象直接調(diào)用被封裝的內(nèi)容上圖展示了對象 obj1 和 obj2 在內(nèi)存中保存的方式,根據(jù)保存格式可以如此調(diào)用被封裝的內(nèi)容:對象.屬性名
demo 2、通過self間接調(diào)用被封裝的內(nèi)容執(zhí)行類中的方法時,需要通過self間接調(diào)用被封裝的內(nèi)容
demo 二、繼承繼承,面向?qū)ο笾械睦^承和現(xiàn)實生活中的繼承相同,即:子可以繼承父的內(nèi)容。例如: 貓可以:喵喵叫、吃、喝、拉、撒 狗可以:汪汪叫、吃、喝、拉、撒吃、喝、拉、撒是貓和狗都具有的功能,而我們卻分別的貓和狗的類中編寫了兩次。如果使用 繼承 的思想,如下實現(xiàn): 動物:吃、喝、拉、撒 貓:喵喵叫(貓繼承動物的功能) 狗:汪汪叫(狗繼承動物的功能)
demo所以,對于面向?qū)ο蟮睦^承來說,其實就是將多個類共有的方法提取到父類中,子類僅需繼承父類而不必一一實現(xiàn)每個方法。注:除了子類和父類的稱謂,你可能看到過 派生類 和 基類 ,他們與子類和父類只是叫法不同而已。 那么問題又來了,多繼承呢?
是否可以繼承多個類
如果繼承的多個類每個類中都定了相同的函數(shù),那么那一個會被使用呢?
1、Python的類可以繼承多個類,Java和C#中則只能繼承一個類
demo 三、多態(tài) Pyhon不支持多態(tài)并且也用不到多態(tài),多態(tài)的概念是應(yīng)用于Java和C#這一類強(qiáng)類型語言中,而Python崇尚“鴨子類型”。
python偽代碼實現(xiàn)java,c#多態(tài)
python“鴨子類型” 類成員 1、字段:
靜態(tài)字段:提供給類里每個對象(方法)使用
普通字段:讓每個方法都有不同的數(shù)據(jù)
2、方法:
靜態(tài)方法: 無需使用對象封裝,用類方法執(zhí)行
類方法: 類方法執(zhí)行,調(diào)用時會顯示出當(dāng)前是哪個類
普通方法: 對象方式執(zhí)行,使用對象中的數(shù)據(jù)
3、特性:
可以獲取特性 也可以設(shè)置特性
一、字段字段包括:普通字段和靜態(tài)字段,他們在定義和使用中有所區(qū)別,而最本質(zhì)的區(qū)別是內(nèi)存中保存的位置不同,
普通字段屬于對象
靜態(tài)字段屬于類
View Code由上述代碼可以看出【普通字段需要通過對象來訪問】【靜態(tài)字段通過類訪問】,在使用上可以看出普通字段和靜態(tài)字段的歸屬是不同的。其在內(nèi)容的存儲方式類似如下圖:
注:靜態(tài)字段只在內(nèi)存中保存一份,普通字段在每個對象中都要保存一份 二、方法方法包括:普通方法、靜態(tài)方法和類方法,三種方法在內(nèi)存中都?xì)w屬于類,區(qū)別在于調(diào)用方式不同。 1、普通方法:由對象調(diào)用;至少一個self參數(shù);執(zhí)行普通方法時,自動將調(diào)用該方法的對象賦值給self; 2、類方法:由類調(diào)用; 至少一個cls參數(shù);執(zhí)行類方法時,自動將調(diào)用該方法的類復(fù)制給cls; 3、靜態(tài)方法:由類調(diào)用;無默認(rèn)參數(shù);
定義方法并使用
相同點:對于所有的方法而言,均屬于類(非對象)中,所以,在內(nèi)存中也只保存一份。不同點:方法調(diào)用者不同、調(diào)用方法時自動傳入的參數(shù)不同。 三、特性 如果你已經(jīng)了解Python類中的方法,那么特性就非常簡單了,因為Python中的屬性其實是普通方法的變種。對于特性,有以下兩個知識點: 1、特性的基本使用 2、特性的兩種定義方式 1、特性的基本使用
特性
由屬性的定義和調(diào)用要注意一下幾點: 1、定義時,在普通方法的基礎(chǔ)上添加 @property 裝飾器; 2、定義時,屬性僅有一個self參數(shù) 3、調(diào)用時,無需括號
方法:foo_obj.func()
屬性:foo_obj.prop注意:屬性存在意義是:訪問屬性時可以制造出和訪問字段完全相同的假象 屬性由方法變種而來,如果Python中沒有屬性,方法完全可以代替其功能。實例:對于主機(jī)列表頁面,每次請求不可能把數(shù)據(jù)庫中的所有內(nèi)容都顯示到頁面上,而是通過分頁的功能局部顯示,所以在向數(shù)據(jù)庫中請求數(shù)據(jù)時就要顯示的指定獲取從第m條到第n條的所有數(shù)據(jù)(即:limit m,n),這個分頁的功能包括: 1、根據(jù)用戶請求的當(dāng)前頁和總數(shù)據(jù)條數(shù)計算出 m 和 n 2、根據(jù)m 和 n 去數(shù)據(jù)庫中請求數(shù)據(jù)
View Code 2、屬性的兩種定義方式屬性的定義有兩種方式: 1、裝飾器 即:在方法上應(yīng)用裝飾器 2、靜態(tài)字段 即:在類中定義值為property對象的靜態(tài)字段 1.1 裝飾器方式經(jīng)典類,具有一種@property裝飾器
View Code新式類,具有三種@property裝飾器
View Code注:1、經(jīng)典類中的屬性只有一種訪問方式,其對應(yīng)被 @property 修飾的方法
2、新式類中的屬性有三種訪問方式,并分別對應(yīng)了三個被@property、@方法名.setter、@方法名.deleter修飾的方法由于新式類中具有三種訪問方式,我們可以根據(jù)他們幾個屬性的訪問特點,分別將三個方法定義為對同一個屬性:獲取、修改、刪除
View Code 1.2 靜態(tài)字段方式,創(chuàng)建值為property對象的靜態(tài)字段當(dāng)使用靜態(tài)字段的方式創(chuàng)建屬性時,經(jīng)典類和新式類無區(qū)別
View Codeproperty的構(gòu)造方法中有個四個參數(shù) 1、第一個參數(shù)是方法名,調(diào)用 對象.屬性 時自動觸發(fā)執(zhí)行方法 2、第二個參數(shù)是方法名,調(diào)用 對象.屬性 = XXX 時自動觸發(fā)執(zhí)行方法 3、第三個參數(shù)是方法名,調(diào)用 del 對象.屬性 時自動觸發(fā)執(zhí)行方法 4、第四個參數(shù)是字符串,調(diào)用 對象.屬性.__doc__ ,此參數(shù)是該屬性的描述信息
View Code由于靜態(tài)字段方式創(chuàng)建屬性具有三種訪問方式,我們可以根據(jù)他們幾個屬性的訪問特點,分別將三個方法定義為對同一個屬性:獲取、修改、刪除
View Code所以,定義屬性共有兩種方式,分別是【裝飾器】和【靜態(tài)字段】,而【裝飾器】方式針對經(jīng)典類和新式類又有所不同。 類成員修飾符 類的所有成員在上一步驟中已經(jīng)做了詳細(xì)的介紹,對于每一個類的成員而言都有兩種形式: 1、公有成員,在任何地方都能訪問 2、私有成員,只有在類的內(nèi)部才能方法 私有成員和公有成員的定義不同:私有成員命名時,前兩個字符是下劃線。(特殊成員除外,例如:__init__、__call__、__dict__等)
1
2
3
4
5
class C:
def __init__(self):
self.name= '公有字段'
self.__foo= "私有字段"
私有成員和公有成員的訪問限制不同: 1、靜態(tài)字段 1、公有靜態(tài)字段:類可以訪問;類內(nèi)部可以訪問;派生類中可以訪問 2、私有靜態(tài)字段:僅類內(nèi)部可以訪問;
公有字段
私有字段2、普通字段 1、公有普通字段:對象可以訪問;類內(nèi)部可以訪問;派生類中可以訪問 2、私有普通字段:僅類內(nèi)部可以訪問;注:如果想要強(qiáng)制訪問私有字段,可以通過 【對象._類名__私有字段明 】訪問(如:obj._C__foo),不建議強(qiáng)制訪問私有成員。
公有字段
私有字段 類的特殊成員 1、 __doc__ 表示類的描述信息
View Code2、 __module__ 和 __class__ __module__ 表示當(dāng)前操作的對象在那個模塊 __class__ 表示當(dāng)前操作的對象的類是什么
lib/test.py
index3、 __init__ 構(gòu)造方法,通過類創(chuàng)建對象時,自動觸發(fā)執(zhí)行。
View Code
繼承父類__init__ 4、 __del__ 析構(gòu)方法,當(dāng)對象在內(nèi)存中被釋放時,自動觸發(fā)執(zhí)行。注:此方法一般無須定義,因為Python是一門高級語言,程序員在使用時無需關(guān)心內(nèi)存的分配和釋放,因為此工作都是交給Python解釋器來執(zhí)行,所以,析構(gòu)函數(shù)的調(diào)用是由解釋器在進(jìn)行垃圾回收時自動觸發(fā)執(zhí)行的。
code 5、 __call__ 對象后面加括號,觸發(fā)執(zhí)行。注:構(gòu)造方法的執(zhí)行是由創(chuàng)建對象觸發(fā)的,即:對象 = 類名() ;而對于 __call__ 方法的執(zhí)行是由對象后加括號觸發(fā)的,即:對象() 或者 類()()
View Code6、 __dict__ 類或?qū)ο笾械乃谐蓡T上文中我們知道:類的普通字段屬于對象;類中的靜態(tài)字段和方法等屬于類,即:
View Code7、 __str__如果一個類中定義了__str__方法,那么在打印 對象 時,默認(rèn)輸出該方法的返回值。
View Code8、__getitem__、__setitem__、__delitem__用于索引操作,如字典。以上分別表示獲取、設(shè)置、刪除數(shù)據(jù)
View Code9、 __iter__ 用于迭代器,之所以列表、字典、元組可以進(jìn)行for循環(huán),是因為類型內(nèi)部定義了 __iter__
View Code
for循環(huán)內(nèi)部語法 單例模式 所謂單例,是指一個類的實例從始至終只能被創(chuàng)建一次。 方法1如果想使得某個類從始至終最多只有一個實例,使用__new__方法會很簡單。Python中類是通過__new__來創(chuàng)建實例的:
1
2
3
4
5
6
7
8
9
10
11
12
13
class Singleton(object):
def __new__(cls,*args,**kwargs):
if not hasattr(cls,'_inst'):
cls._inst=super(Singleton,cls).__new__(cls,*args,**kwargs)
return cls._inst
if __name__=='__main__':
class A(Singleton):
def __init__(self,s):
self.s=s
a=A('apple')
b=A('banana')
print(id(a),a.s)
print(id(b),b.s)
結(jié)果:
1
2
29922256 banana
29922256 banana
通過__new__方法,將類的實例在創(chuàng)建的時候綁定到類屬性_inst上。如果cls._inst為None,說明類還未實例化,實例化并將實例綁定到cls._inst,以后每次實例化的時候都返回第一次實例化創(chuàng)建的實例。注意從Singleton派生子類的時候,不要重載__new__。 方法2當(dāng)你編寫一個類的時候,某種機(jī)制會使用類名字,基類元組,類字典來創(chuàng)建一個類對象。新型類中這種機(jī)制默認(rèn)為type,而且這種機(jī)制是可編程的,稱為元類__metaclass__ 。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
class Singleton(type):
def __init__(self,name,bases,class_dict):
super(Singleton,self).__init__(name,bases,class_dict)
self._instance=None
def __call__(self,*args,**kwargs):
if self._instanceis None:
self._instance=super(Singleton,self).__call__(*args,**kwargs)
return self._instance
if __name__=='__main__':
class A(object):
__metaclass__=Singleton
a=A()
b=A()
print(id(a),id(b))
結(jié)果:
1
34248016 34248016
id是相同的。例子中我們構(gòu)造了一個Singleton元類,并使用__call__方法使其能夠模擬函數(shù)的行為。構(gòu)造類A時,將其元類設(shè)為Singleton,那么創(chuàng)建類對象A時,行為發(fā)生如下:A=Singleton(name,bases,class_dict),A其實為Singleton類的一個實例。創(chuàng)建A的實例時,A()=Singleton(name,bases,class_dict)()=Singleton(name,bases,class_dict).__call__(),這樣就將A的所有實例都指向了A的屬性_instance上,這種方法與方法1其實是相同的。 方法4最簡單的方法:
1
2
3
class singleton(object):
pass
singleton=singleton()
將名字singleton綁定到實例上,singleton就是它自己類的唯一對象了。 方法5
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
class ConnectionPool:
__instance= None
def __init__(self):
self.ip= "192.168.1.1"
self.port= 3306
self.username= "zhangyanlin"
self.pwd= 123456
@staticmethod
def get_instance():
if ConnectionPool.__instance:
return ConnectionPool.__instance
else:
ConnectionPool.__instance= ConnectionPool()
return ConnectionPool.__instance
obj1= ConnectionPool()
print(obj1.get_instance())
obj2= ConnectionPool()
print(obj2.get_instance())
obj3= ConnectionPool()
print(obj3.get_instance())
定義靜態(tài)方法,判斷讓所有只用第一個對象在內(nèi)存中創(chuàng)建的ID
總結(jié)
以上是生活随笔為你收集整理的python完全支持面向对象编程_python面向对象编程----009的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: python3一个中文3个字符_高手接招
- 下一篇: python基础内容_python基础-