日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程语言 > python >内容正文

python

Python深入类和对象

發(fā)布時間:2023/12/6 python 37 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Python深入类和对象 小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.

一. 鴨子類型和多態(tài)

  1.什么是鴨子類型:

    在程序設(shè)計(jì)中,鴨子類型(英語:Duck typing)是動態(tài)類型和某些靜態(tài)語言的一種對象推斷風(fēng)格。"鴨子類型"像多態(tài)一樣工作,但是沒有繼承?!傍喿宇愋汀钡恼Z言是這么推斷的:一只鳥走起來像鴨子、游起泳來像鴨子、叫起來也像鴨子,那它就可以被當(dāng)做鴨子。也就是說,它不關(guān)注對象的類型,而是關(guān)注對象具有的行為(方法)。

    可以看出,Cat,Dog,Duck中有相同的方法say(),當(dāng)有一個函數(shù)調(diào)用Duck類時并調(diào)用say()方法,我們傳入Cat類和Dog類也行,函數(shù)并不會檢查對象是不是Duck,而是只要你有這樣的方法就能運(yùn)行。

  

如,列表的extend()方法只要參數(shù)是一個可迭代的對象就可以(list,set,tuple)

    還有前面的例子,只要實(shí)現(xiàn)了類中的__getitem__()魔法函數(shù),就可以把類當(dāng)作一個collection,實(shí)現(xiàn)啊__iter__和__next__就可以當(dāng)作一個iterator。python中的鴨子類型允許我們使用任何提供所需方法的對象,而不需要迫使它成為一個子類。

  2.多態(tài):

    由于python屬于動態(tài)語言,當(dāng)你定義了一個基類和基類中的方法,并編寫幾個繼承該基類的子類時,由于python在定義變量時不指定變量的類型,而是由解釋器根據(jù)變量內(nèi)容推斷變量類型的(也就是說變量的類型取決于所關(guān)聯(lián)的對象),這就使得python的多態(tài)不像是c++或java中那樣,定義一個基類類型變量而隱藏了具體子類的細(xì)節(jié)。

二. 抽象基類(abc模塊)

  1.在某些情況下判斷某個對象的類型:

    

?

  2.強(qiáng)制某個子類必須實(shí)現(xiàn)某些方法:

    

  3.模擬抽象基類:

?    3.1利用內(nèi)置拋錯模擬:(但只有調(diào)用某些方法時才會拋異常)

      

1 class CacheBase(): 2 def get(self,key): 3 #默認(rèn)拋出異常(Python內(nèi)置錯誤) 4 raise NotImplementedError 5 def set(self,key,value): 6 raise NotImplementedError 7 #繼承重寫就不會拋異常 8 class Rediscatche(CacheBase): 9 def get(self,key): 10 pass 11 def set(self,key,value): 12 pass 13 cachebase=Rediscatche() 14 cachebase.set("key","value")

    3.2利用內(nèi)置的abc模塊:

?

    3.3通用的抽象基類(collections.abc模塊,推薦使用多繼承mixin,以防抽象基類設(shè)計(jì)過度):

      有可遍歷,可哈希的等等抽象基類

?

?

     ? ?這些抽象基類都有一個魔法函數(shù)__subclasshook__():

      作用:Comp()沒有繼承Sized,但是卻能判斷出是Sized類型。

         __subclasshook__()會判斷傳入的C是否有“__len__”這個方法,有就返回為True

?

?

?

?

三. 使用isintance而不是type

   isinstance內(nèi)部會去檢查它的繼承鏈,就可以判斷它是A的類型,而type是指向B那個對象,判斷是否和B是同一個對象。盡量應(yīng)使用isinstance,而不是type,以免誤判。

  

   is和==:

      is是判斷兩者是不是一個對象(即id是否相同),而==是判斷值是否相同。如type(b)指向的是B這個對象,雖然B繼承于A,但是A和B是兩個不同的對象。? ? ? ? ?

四. 類變量和對象變量

  注:1.魔法函數(shù)__init__中self是實(shí)例化對象,中的參數(shù)是對象變量,在實(shí)例化后調(diào)用變量是向上查找(即先查找對象變量,后查找類變量),類變量可以直接通過類訪問;

    2.類變量是所有實(shí)例共享的

通過類修改類變量

通過實(shí)例對象修改變量


五. 類屬性和實(shí)例屬性以及查找順序

  1.向上查找,即先查找對象變量(實(shí)例屬性),后查找類屬性:

  2.多繼承采用MRO(【Method Resolution Order】:方法解析順序)算法:

    Python語言包含了很多優(yōu)秀的特性,其中多重繼承就是其中之一,但是多重繼承會引發(fā)很多問題,比如二義性,Python中一切皆引用,這使得他不會像C++一樣使用虛基類處理基類對象重復(fù)的問題,但是如果父類存在同名函數(shù)的時候還是會產(chǎn)生二義性,Python中處理這種問題的方法就是MRO。

DFS:深度優(yōu)先算法,這樣查詢順序?yàn)锳->B->D->C->E

?

?這樣就會出現(xiàn)問題(菱形繼承):如果C繼承D覆蓋D中的某方法,在調(diào)用時是先查詢D,然后查詢C,則查詢的方法是D中的,而不是C中重寫的,因此在Python2

   后改成了廣度優(yōu)先的算法。

廣度優(yōu)先算法,這就解決了菱形繼承,但是在第一種又出現(xiàn)了問題

如D和C中如果有個同名的方法,則會調(diào)用C中的方法,而不是D中的,而B是繼承D的,因此從Python2.3后都統(tǒng)一為C3算法

  3.C3算法(參考:https://www.cnblogs.com/LLBFWH/p/10009064.html):  

    求某一類在多繼承中的繼承順序:
    類的mro == [類] + [父類的繼承順序] + [父類2的繼承順序]
    如果從左到右的第一個類在后面的順序中出現(xiàn),那么就提取出來到mro順序中
    [ABCD] + [EO] --> A = [BCD] + [EO]
    如果從左到右的第一個類在后面的順序中出現(xiàn),且在后面的順序中也是第一位,那么就提出來到mro順序中
    [ABCD] + [AEO] --> A = [BCD] + [EO]
    如果從左到右的第一個類在后面的順序中出現(xiàn),但不是在第一位,那么應(yīng)該繼續(xù)往后找,找到符合規(guī)則的項(xiàng)目
    [ABCD] + [EAO] --> E = [ABCD] + [AO]
    [ABCD] + [EAO] + [GEO] --> G = [ABCD] + [EAO] + [EO]
    [ABCD] + [EAO] + [EO] --> GE = [ABCD] + [AO] + [O]
    關(guān)鍵結(jié)論:
        這個類沒有發(fā)生繼承,他的順序永遠(yuǎn)是[類o]
      ? 只要是單繼承,不是多繼承,那么mro順序就是從子類到父類的順序

  4.查找順序:

    4.1菱形繼承:(Python2.3以前為經(jīng)典類,默認(rèn)不繼承object(D),而2.3以后為新式類,默認(rèn)繼承object,即最后查找object類)

    

    4.2分別繼承:

?

?

    

六. 靜態(tài)方法、類方法以及對象方法

  1.實(shí)例方法:self為實(shí)例對象

  

?

  2.靜態(tài)方法:(相當(dāng)于普通的函數(shù))

    (注:采用硬編碼,如果類名改變,相應(yīng)的靜態(tài)方法中也要改變,如下面的Date改變,則parse_from_string中Date也相應(yīng)改變)

    

利用外部對參數(shù)處理傳入(每次都需要處理,麻煩)

 

利用靜態(tài)方法

    靜態(tài)方法用處:如在判斷傳入的參數(shù)是否為合法字符串,這是不用返回類對象,因此不用傳入類(類方法)

      

?

  3.類方法:(傳遞的是類cls)

    注:相比靜態(tài)方法,不是采用硬編碼,無論類名稱是什么,都不用修改類方法,且傳遞的是類(cls,只是名稱,可以修改)

     

?

七. 數(shù)據(jù)封裝和私有屬性

  1.私有屬性:

    

無法實(shí)例或類直接訪問私有屬性,只有通過類中的公共方法get_age間接訪問

  2.私有屬性原理:

    把具有雙下劃線的屬性(如__birthday變?yōu)閇_classname__attr]即_User__birthday),因此不是從語言層面解決了絕對私有性,只是加了一些小技巧。主要只是讓我們書寫更加規(guī)范,沒有絕對的安全,也可以解決同樣的變量名沖突的問題。如另一個類繼承User,且也有__birthday,則根據(jù)規(guī)則是不一樣的

    

仍然能訪問

八. python對象的自省機(jī)制

  1.概念:

    自省是通過一定的機(jī)制查詢到對象的內(nèi)部結(jié)構(gòu)

  2.__dict__,dir的使用:

    2.1通過dict查找屬性:

   

實(shí)例的屬性,但是通過name屬性卻能查找到(向上查找,name屬性User類這個對象)

?

類屬性,含有模板,文檔,屬性,弱引用等

     2.2通過__dict__添加修改屬性:

      

?

?    2.3通過dir查找屬性(會列出所有屬性,比__dict__更加詳細(xì)): 

  

只有屬性名稱,沒有屬性值,還可以對list等使用

九. super函數(shù)

  

  1.如果想調(diào)用A中的構(gòu)造函數(shù):

      Python2:super(B,self).__init__()

          

      Python3中:super().__init__()

  2.既然重寫A的構(gòu)造函數(shù),為什么還要調(diào)用super:

    很好的重用代碼,如某個參數(shù)需要父類的構(gòu)造函數(shù)處理,就可以調(diào)用super函數(shù)把參數(shù)交給父類的構(gòu)造函數(shù)處理

    

將name交給Thread的構(gòu)造函數(shù)處理

  3.super執(zhí)行順序: 

    super并不是直接調(diào)用父類,而是根據(jù)MRO算法的調(diào)用順序(因此先是C,然后是A)

?

十. django rest framework中對多繼承使用的經(jīng)驗(yàn)

  1.建議:

    盡量不要使用多繼承,以免造成混亂

  2.mixin多繼承案例(如django restframework中的mixins):

    1.mixin類功能單一;

    2.不和基類關(guān)聯(lián),可以和任意基類組合,基類可以不和mixin關(guān)聯(lián)就能初始化成功;

    3.在mixin中不要使用super函數(shù);

    4.盡量以Mixin結(jié)尾

十一.python中的with語句

  1.try...except語句:

    except語句中將2壓入堆棧中,finally又將4壓入堆棧中,所以在取數(shù)據(jù)時直接從棧頂取數(shù)據(jù),因此是4,如果沒有finally則是前面的(如果要操作數(shù)據(jù)庫,文件等,就需要在try中,except,finally中書寫關(guān)閉連接,文件的邏輯)。

  2.上下文管理器:

    上下文管理器協(xié)議(需要實(shí)現(xiàn)兩個魔法函數(shù)__enter__和__exit__):

      需要在__enter__中獲取資源,在__exit__釋放資源,只要滿足這個協(xié)議就可以用with語句使用

      ?

?

                                  

十二. contextlib實(shí)現(xiàn)上下文管理器

    相當(dāng)于簡化__enter__和__exit__:@contextlib.contextmanager裝飾器將__enter__和__exit__合起來并進(jìn)行了一系列操作

?

十三.參考文獻(xiàn):

  MRO算法介紹

轉(zhuǎn)載于:https://www.cnblogs.com/lyq-biu/p/10310174.html

總結(jié)

以上是生活随笔為你收集整理的Python深入类和对象的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯,歡迎將生活随笔推薦給好友。