Python深入類和對象

一. 鴨子類型和多態

  1.什么是鴨子類型:

    在程序設計中,鴨子類型(英語:Duck typing)是動態類型和某些靜態語言的一種對象推斷風格。"鴨子類型"像多態一樣工作,但是沒有繼承。“鴨子類型”的語言是這么推斷的:一只鳥走起來像鴨子、游起泳來像鴨子、叫起來也像鴨子,那它就可以被當做鴨子。也就是說,它不關注對象的類型,而是關注對象具有的行為(方法)。

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

  

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

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

  2.多態:

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

二. 抽象基類(abc模塊)

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

    

?

  2.強制某個子類必須實現某些方法:

    

  3.模擬抽象基類:

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

      

 1 class CacheBase():
 2     def get(self,key):
 3         #默認拋出異常(Python內置錯誤)
 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利用內置的abc模塊:

?

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

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

?

?

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

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

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

?

?

?

?

三. 使用isintance而不是type

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

  

   is和==:

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

四. 類變量和對象變量

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

    2.類變量是所有實例共享的

通過類修改類變量

通過實例對象修改變量


五. 類屬性和實例屬性以及查找順序

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

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

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

DFS:深度優先算法,這樣查詢順序為A->B->D->C->E

?

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

   后改成了廣度優先的算法。

廣度優先算法,這就解決了菱形繼承,但是在第一種又出現了問題

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

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

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

  4.查找順序:

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

    

    4.2分別繼承:

?

?

    

六. 靜態方法、類方法以及對象方法

  1.實例方法:self為實例對象

  

?

  2.靜態方法:(相當于普通的函數)

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

    

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

 

利用靜態方法

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

      

?

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

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

     

?

七. 數據封裝和私有屬性

  1.私有屬性:

    

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

  2.私有屬性原理:

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

    

仍然能訪問

八. python對象的自省機制

  1.概念:

    自省是通過一定的機制查詢到對象的內部結構

  2.__dict__,dir的使用:

    2.1通過dict查找屬性:

   

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

?

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

     2.2通過__dict__添加修改屬性:

      

?

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

  

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

九. super函數

  

  1.如果想調用A中的構造函數:

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

          

      Python3中:super().__init__()

  2.既然重寫A的構造函數,為什么還要調用super:

    很好的重用代碼,如某個參數需要父類的構造函數處理,就可以調用super函數把參數交給父類的構造函數處理

    

將name交給Thread的構造函數處理

  3.super執行順序: 

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

?

十. django rest framework中對多繼承使用的經驗

  1.建議:

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

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

    1.mixin類功能單一;

    2.不和基類關聯,可以和任意基類組合,基類可以不和mixin關聯就能初始化成功;

    3.在mixin中不要使用super函數;

    4.盡量以Mixin結尾

十一.python中的with語句

  1.try...except語句:

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

  2.上下文管理器:

    上下文管理器協議(需要實現兩個魔法函數__enter__和__exit__):

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

      ?

?

                                  

十二. contextlib實現上下文管理器

    相當于簡化__enter__和__exit__:@contextlib.contextmanager裝飾器將__enter__和__exit__合起來并進行了一系列操作

?

十三.參考文獻:

  MRO算法介紹

轉載于:https://www.cnblogs.com/lyq-biu/p/10310174.html

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/news/280535.shtml
繁體地址,請注明出處:http://hk.pswp.cn/news/280535.shtml
英文地址,請注明出處:http://en.pswp.cn/news/280535.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

linux中/usr下文件權限修改setuid導致的問題

2019獨角獸企業重金招聘Python工程師標準>>> 在Ubuntu系統中因為一些原因我使用如下命令修改了/usr目錄的擁有者權限: chown -R root:root /usr結果直接導致系統無法正常啟動,通過跟蹤系統啟動日志/var/log/syslog找到如下失敗原因&#xff1…

[轉載]unix環境高級編程備忘:理解保存的設置用戶ID,設置用戶ID位,有效用戶ID,實際用戶ID...

轉載自http://www.cnblogs.com/stemon/p/5287631.html 一、基本概念 實際用戶ID(RUID):用于標識一個系統中用戶是誰,一般是在登錄之后,就被唯一的確定,就是登錄的用戶的uid。 有效用戶ID(EUID):用于系統決定用戶對系統…

django20:BBS網頁設計/注冊功能/驗證碼代碼

表設計 注冊功能 """ 1.注冊功能需要forms組件 不同功能,可單獨一個py文件2.利用forms組件渲染前端標簽1.利用ajax提交2.forms組件獲取用戶數據的數據。$(#form).serializeArray()獲取forms標簽所有用戶普通鍵值對的數據3. 手動渲染頭像label里面內…

用最少的代碼打造一個Mini版的gRPC框架

在《用最少的代碼模擬gRPC四種消息交換模式》中,我使用很簡單的代碼模擬了gRPC四種消息交換模式(Unary、Client Streaming、Server Streaming和Duplex Streaming),現在我們更近一步,試著使用極簡的方式打造一個gRPC框架…

Windows 10的下一個更新將在您觀看視頻時隱藏通知

Windows 10’s Focus Assist feature temporarily hides incoming notifications. In Windows 10’s next update, Focus Assist can activate when you’re using any full-screen app, whether that’s YouTube in a browser, Netflix, or a desktop video player like VLC. …

Ubuntu安裝Samba文件共享服務器(NAS)

終于有點時間來解決下家中NAS需求了。一般自制NAS,只有選Samba。速度比FTP快,便利性比Windows文件夾共享好,設置多等等。 ?參考:samba簡介 安裝Samba $ sudo apt-get update $ sudo apt-get install samba samba-common-bin 核心…

剛畢業的ERP實施顧問做甲方

我剛畢業進入了一家小公司做ERP實施顧問,是一個臺灣的ERP軟件,就簡單培訓了一天,第二天就進入一家客戶公司解決問題,軟件都還沒有熟悉呢,更別說業務流程了,一天下來,人家員工問一個問題我記下來…

django21:admin后臺管理\media配置\圖片防盜鏈\暴露后端資源\路由分發\時間分類

admin后臺管理 創建超級用戶 createsuperuser 1.到應用下的admin.py注冊模型表 from django.contrib import admin from blog import models # Register your models here.admin.site.register(models.UserInfo) admin.site.register(models.Article) admin.site.register(m…

Flask博客開發——Tinymce編輯器

之前Flask博客的文本編輯器比較簡陋,這里為博客添加個優雅易用的Tinymce文本編輯器。 github見:https://github.com/ikheu/my_flasky 1 項目中添加Tinymce 下載好Tinymce包以及語言包,并添加到項目中。添加到項目的方法,參考了這篇…

Go開發Struct轉換成map兩種方式比較

最近做Go開發的時候接觸到了一個新的orm第三方框架gorose,在使用的過程中,發現沒有類似beego進行直接對struct結構進行操作的方法,有部分API是通過map進行數據庫相關操作,那么就需要我們把struct轉化成map,下面是是我嘗…

Hello, Raspberry Pi.

1.概要最近在研究自動升級開源項目的時候偶然想到IoT領域的自動升級,突然想起2016年買的樹莓派(Raspberry Pi)。那就分享一下如何入門樹莓派的教程,我當時一共買了兩塊一款是Raspberry Pi 3b(2016年價格259元去年以抽獎…

supersu_SuperSU已從Play商店中刪除,這是替代使用的方法

supersuSuperSU has long been a staple in the rooted Android community. For years, the process for getting a rooted handset was: unlock the bootloader, flash a custom recovery, install SuperSU. That’s just how it was. 長期以來,SuperSU一直是扎根于…

Oracle 11g DRCP連接方式——基本原理

學習Oracle是一個復雜、繁瑣的過程。在浩如煙海的Oracle官方資料、新特性、MOS資料和各種Internal知識面前,我們總是覺得力不從心、不知所措。但是,這往往也就是我們不斷堅持、積累和追尋的樂趣。  在Oracle 11g中,提出了突破傳統專用/共享…

django項目開發1:搭建虛擬環境

需求 不同項目依賴不同模塊版本,不能共用一套環境,虛擬環境。在系統的python環境安裝 安裝 pip3 install virtualenv pip3 install virtualenvwrapper-win環境變量 # 配置環境變量: # 控制面板 > 系統和安全 > 系統 > 高級系統設…

IPC之——消息隊列

消息隊列作用&#xff1a; 可以用于兩個沒有聯系的進程間通信&#xff0c;創建一個消息隊列類似于打開了一個文件&#xff0c;兩個不同的進程都可以進行操作 消息隊列之函數介紹&#xff1a; 頭文件&#xff1a;<sys/type.h> <sys/ipc.h> <sys/msg.h> 1.msgg…

【招聘(上海)】To B數字化營銷公司-市場易,直招.NET后端研發工程師

【招聘背景】公司&#xff1a;上海光潾網絡科技有限公司成立于2016年&#xff0c;系上海市高新技術企業&#xff0c;2021年獲數千萬A輪融資項目&#xff1a;公司自主研發營銷自動化SaaS平臺- 市場易 (Custouch) &#xff0c;通過數字手段為B2B營銷賦能&#xff0c;現服務100多家…

div 包裹_如何查看到達之前收到的包裹和郵件

div 包裹The United States Postal Service, UPS, and FedEx all offer online dashboards where you can see exactly what packages (and letters, in the case of the US Postal Service) are scheduled to arrive at your address. They’ll even email and send you text …

py文件的運行

安裝過程及配置 安裝過程準備&#xff1a; 下載好Python的安裝程序后&#xff0c;開始安裝&#xff0c;在進入安裝界面后一定確保勾選將Python加入到系統環境變量的路徑里。如圖所示&#xff1a; 2如果沒有選取&#xff0c;那么按照下面的步驟進行操作。在桌面上用鼠標右鍵點擊…

加州大學信息科學院長:數據科學課程不只是工程師才修的

一般在考慮圍繞數據科學的基礎教育時&#xff0c;傳統上的重點仍停留在計算和工程等硬性技能上。不過&#xff0c;在周四于紐約市召開的GigaOm結構數據&#xff08;Structure Data&#xff09;會議上&#xff0c;美國加州大學伯克利分校信息科學院長AnnaLee Saxenian教授表示&a…

查看安裝軟件/Select-object/Where-Object xxx -like

查看已安裝軟件 1.通過注冊列表查看 $Path(HKLM:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*,HKLM:\SOFTWARE\WOW6432Node\Microsoft\Windows\CurrentVersion\Uninstall\*,HKCU:\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\*,HKCU:\SOFTWARE\WOW6432…