Ⅰ python類的繼承與多態詳細介紹
類(Class): 用來描述具有相同的屬性和方法的對象的集合。
類變數:類變數在整個實例化的對象中是公用的。類變數定義在類中且在函數體之外。類變數通常不作為實例變數使用。
類有一個名為 __init__() 的特殊方法(構造方法),該方法在類實例化時會自動調用
self:self 代表的是類的實例,代表當前對象的地址,而 self.class 則指向類。
類調用 Car.weight
實例化 car01=Car(5)
實例對象調用 car01.weght
我們在構造類時,Python3默認我們繼承了object這個基類,我個人理解object就是個空的類,可以不用管為何要在括弧中寫上object,這是Python3的特性,在python2中如果你沒有寫object的話不會默認繼承了object這個基類。
同樣的我們自己希望繼承的父類只需要把objetc改為我們自己定義的類名即可。子類中可以擁有父類中所有的公有屬性和方法,但是可以通過在變數名前加下劃線使其變為私有,這樣子類就不可以訪問父類中的成員了。
以下三個公交車類的父類均為客車類,我們可以寫一個funcs方法使得每次調用funcs方法時,傳入不同的對象以執行不同的func方法,具體實現如下:
主函數 :
可以看到,我將小 汽車 實例化為帶有重量為5t的一個具體對象,將客車實例化為帶有重量為20t的一個具體對象,將三個公交車實例化為帶有重量為15t的一個具體對象.
如上圖所示,我每次在調用funcs方法時都傳入了一個實例化對象,funcs根據不同的對象執行相應的內部方法。
Ⅱ Python類的多重繼承問題深入分析
Python類的多重繼承問題深入分析
首先得說明的是,Python的類分為經典類 和 新式類
經典類是python2.2之前的東西,但是在2.7還在兼容,但是在3之後的版本就只承認新式類了
新式類在python2.2之後的版本中都可以使用
經典類和新式類的區別在於:
經典類是默認沒有派生自某個基類的,而新式類是默認派生自object這個基類的:
代碼如下:
# old style
class A():pass
# new style
class A(obejct):pass
2.經典類在類多重繼承的時候是採用從左到右深度優先原則匹配方法的..而新式類是採用C3演算法(不同於廣度優先)進行匹配的
3.經典類是沒有__MRO__和instance.mro()調用的,而新式類是有的.
為什麼不用經典類,要更換到新式類
因為在經典類中的多重繼承會有些問題...可能導致在繼承樹中的方法查詢繞過後面的父類:
代碼如下:
class A():
def foo1(self):
print "A"
class B(A):
def foo2(self):
pass
class C(A):
def foo1(self):
print "C"
class D(B, C):
pass
d = D()
d.foo1()
按照經典類的查找順序從左到右深度優先的規則,在訪問d.foo1()的時候,D這個類是沒有的..那麼往上查找,先找到B,裡面沒有,深度優先,訪問A,找到了foo1(),所以這時候調用的是A的foo1(),從而導致C重寫的foo1()被繞過.
所以python引入了新式類的概念,每個基類都繼承自object並且,他的匹配規則也從深度優先換到了C3
C3演算法
C3演算法是怎麼做匹配的呢..在問答版塊上面討論之後,歸結如下:
C3演算法的一個核心是merge.
在merge列表中,如果第一個序列mro的第一個類是出現在其它序列,並且也是第一個,或者不出現其它序列,那麼這個類就會從這些序列中刪除,並合到訪問順序列表中
比如:(引用問題中zhuangzebo的回答@zhuangzebo)
代碼如下:
class A(O):pass
class B(O):pass
class C(O):pass
class D(A,B):pass
class E(C,D):pass
首先需要知道 O(object)的mro(method resolution order)列表是[O,]
那麼接下來是:
代碼如下:
mro(A) = [A, O]
mro(B) = [B, O]
mro(C) = [C, O]
mro(D) = [D] + merge(mro(A), mro(B), [A, B])
= [D] + merge([A, O], [B, O], [A, B])
= [D, A] + merge([O], [B, O], [B])
= [D, A, B] + merge([O], [O])
= [D, A, B, O]
mro(E) = [E] + merge(mro(C), mro(D), [C, D])
= [E] + merge([C, O], [D, A, B, O], [C, D])
= [E, C] + merge([O], [D, A, B, O], [D])
= [E, C, D] + merge([O], [A, B, O])
= [E, C, D, A, B] + merge([O], [O])
= [E, C, D, A, B, O]
然後還有一種特殊情況:
比如:
merge(DO,CO,C) 先merge的是D
merge(DO,CO,C) 先merge的是C
意思就是.當出現有 一個類出現在兩個序列的頭(比如C) 這種情況和 這個類只有在一個序列的頭(比如D) 這種情況同時出現的時候,按照順序方式匹配。
新式類生成的訪問序列被存儲在一個叫MRO的只讀列表中..
你可以使用instance.__MRO__或者instance.mro()來訪問
最後匹配的時候就按照MRO序列的順序去匹配了
C3和廣度優先的區別:
舉個例子就完全明白了:
代碼如下:
class A(object):pass
class B(A):pass
class C(B):pass
class D(A):pass
class E(D):pass
class F(C, E):pass
按照廣度優先遍歷,F的MRO序列應該是[F,C,E,B,D,A]
但是C3是[F,E,D,C,B,A]
意思是你可以當做C3是在一條鏈路上深度遍歷到和另外一條鏈路的交叉點,然後去深度遍歷另外一條鏈路,最後遍歷交叉點
新式類和經典類的super和按類名訪問問題
在經典類中,你如果要訪問父類的話,是用類名來訪問的..
代碼如下:
class A():
def __init__(self):
print "A"
class B(A):
def __init__(self):
print "B"
A.__init__(self) #python不會默認調用父類的初始化函數的
這樣子看起來沒三問題,但是如果類的繼承結構比較復雜,會導致代碼的可維護性很差..
所以新式類推出了super這個東西...
代碼如下:
class A():
def __init__(self):
print "A"
class B(A):
def __init__(self):
print "B"
super(B,self).__init__()
這時候,又有一個問題:當類是多重繼承的時候,super訪問的是哪一個類呢?
super實際上是通過__MRO__序列來確定訪問哪一個類的...實際上就是調用__MRO__中此類後面的一個類的方法.
比如序列為[F,E,D,C,B,A]那麼F中的super就是E,E的就是D
super和按照類名訪問 混合使用帶來的坑
代碼如下:
class A(object):
def __init__(self):
print "enter A"
print "leave A"
class B(object):
def __init__(self):
print "enter B"
print "leave B"
class C(A):
def __init__(self):
print "enter C"
super(C, self).__init__()
print "leave C"
class D(A):
def __init__(self):
print "enter D"
super(D, self).__init__()
print "leave D"
class E(B, C):
def __init__(self):
print "enter E"
B.__init__(self)
C.__init__(self)
print "leave E"
class F(E, D):
def __init__(self):
print "enter F"
E.__init__(self)
D.__init__(self)
print "leave F"
這時候列印出來是:
代碼如下:
enter F
enter E
enter B
leave B
enter C
enter D
enter A
leave A
leave D
leave C
leave E
enter D
enter A
leave A
leave D
leave F
可以看出來D和A的初始化函數被亂入了兩次!
按類名訪問就相當於C語言之前的GOTO語句...亂跳,然後再用super按順序訪問..就有問題了
所以建議就是要麼一直用super,要麼一直用按照類名訪問
最佳實現:
避免多重繼承
super使用一致
不要混用經典類和新式類
調用父類的時候注意檢查類層次
以上便是本人對於python類的繼承的認識了,希望對大家能有所幫助
Ⅲ python的用途和優點
python的用途:
python也是一門程序語言。能寫各種各樣的程序。
優點:
1.支持OOP編程 從根本
上講Python仍是一種面向對象的語言,支持多態、繼承等高級概念,在Python里使用OOP十分容易 沒有C++、java那樣復雜,但不必做Python下OOp高手,夠用即可。
2. 免費Python的使用是完全免費的,您可以從網路上免費下載、安裝使用, Python上的其他程序包,也可下載安裝使用。 Python的免費的同時又有很多的的社區對用戶的提問提出快速的技術支持,學習和使用Python技術不再是一個人在戰斗!
3. 可移植性 Python的實現是用ansi c編寫的,可以運行在目前所有主流平台上,手機、pad上均可運行Python程序,其下的程序包也具有可移植性。
4. 功能強大 從特性的觀點上看,Python是一個混合體,他豐富的工具集使得他介於傳統的腳本語言和系統語言之間。
拓展資料:
設計定位
Python的設計哲學是"優雅"、"明確"、"簡單"。因此,Perl語言中"總是有多種方法來做同一件事"的理念在Python開發者中通常是難以忍受的。Python開發者的哲學是"用一種方法,最好是只有一種方法來做一件事"。
在設計Python語言時,如果面臨多種選擇,Python開發者一般會拒絕花俏的語法,而選擇明確的沒有或者很少有歧義的語法。由於這種設計觀念的差異,Python源代碼通常被認為比Perl具備更好的可讀性,並且能夠支撐大規模的軟體開發。這些准則被稱為Python格言。在Python解釋器內運行import this可以獲得完整的列表。
Python開發人員盡量避開不成熟或者不重要的優化。一些針對非重要部位的加快運行速度的補丁通常不會被合並到Python內。所以很多人認為Python很慢。不過,根據二八定律,大多數程序對速度要求不高。在某些對運行速度要求很高的情況,Python設計師傾向於使用JIT技術,或者用使用C/C++語言改寫這部分程序。可用的JIT技術是PyPy。
Python是完全面向對象的語言。函數、模塊、數字、字元串都是對象。並且完全支持繼承、重載、派生、多繼承,有益於增強源代碼的復用性。Python支持重載運算符和動態類型。相對於Lisp這種傳統的函數式編程語言,Python對函數式設計只提供了有限的支持。有兩個標准庫(functools, itertools)提供了Haskell和Standard ML中久經考驗的函數式程序設計工具。
雖然Python可能被粗略地分類為"腳本語言"(script language),但實際上一些大規模軟體開發計劃例如Zope、Mnet及BitTorrent,Google也廣泛地使用它。Python的支持者較喜歡稱它為一種高級動態編程語言,原因是"腳本語言"泛指僅作簡單程序設計任務的語言,如shellscript、VBScript等只能處理簡單任務的編程語言,並不能與Python相提並論。
Python本身被設計為可擴充的。並非所有的特性和功能都集成到語言核心。Python提供了豐富的API和工具,以便程序員能夠輕松地使用C語言、C++、Cython來編寫擴充模塊。Python編譯器本身也可以被集成到其它需要腳本語言的程序內。
因此,很多人還把Python作為一種"膠水語言"(glue language)使用。使用Python將其他語言編寫的程序進行集成和封裝。在Google內部的很多項目,例如Google Engine使用C++編寫性能要求極高的部分,然後用Python或Java/Go調用相應的模塊。
Ⅳ python中的繼承和多態
繼承:在已有類的基礎上創建新類,這其中的一種做法就是讓一個類從另一個類那裡將屬性和方法直接繼承下來,從而減少重復代碼的編寫。
1.提供繼承信息的我們稱之為父類,也叫超類或基類;2.得到繼承信息的我們稱之為子類,也叫派生類或衍生類。3.子類除了繼承父類提供的屬性和方法,還可以定義自己特有的屬性和方法,所以子類比父類擁有的更多的能力
多態:子類在繼承了父類的方法後,通過方法重寫我們可以讓父類的同一個行為在子類中擁有不同的實現版本,這個就是多態。
Ⅳ python下的抽象類的用途和意義
抽象方法是基類中定義的方法,但卻沒有任何實現。在java中,可以把方法申明成一個介面。而在python中實現一個抽象方法的簡單的方法是:
class Sheep(object):
def get_size(self):
raise NotImplementedError
任何從Sheep繼承下來的子類必須實現get_size方法。否則就會產生一個錯誤。但這種實現方法有個缺點。定義的子類只有調用那個方法時才會拋錯。這里有個簡單方法可以在類被實例化後觸發它。使用python提供的abc模塊。
import abc
class Sheep(object):
__metaclass__ = abc.ABCMeta
@abc.absractmethod
def get_size(self):
return
這里實例化Sheep類或任意從其繼承的子類(未實現get_size)時候都會拋出異常。
因此,通過定義抽象類,可以定義子類的共同method(強制其實現)。
Ⅵ python已經自動化了,大家一般用什麼測試框架
首先我們需要明白自動化測試框架更傾向於一種設計思想 ,這種思想指導工具的使用或者自研開發,並且不是只能使用僅僅一種框架,結合被測系統本身特性一般是選擇多種測試框架的組合,來滿足測試和設計需求(開發、維護角度)。
錄制回放測試框架
錄制回放測試框架所採用的原理是通過錄制應用程序產生的線性腳本進行回放從而達到自動化測試的目的。
優點:對測試人員測試開發能力要求最低,通過錄制就可以得到所需腳本。
缺點:一般不具有邏輯判斷的能力 ,可維護性差 ,效率低。
適應場景:不推薦,傳統的UI自動化測試逐步弱化。關於U自動化,一定要清楚 被測系統是否滿足開展自動化的條件,在被測系統變動頻繁的項目中,開展UI自動化無疑是挖了一個很大的坑,其後期維護工作足以讓大心疲憊,被迫放棄自動化測試。
測試庫構架框架(The Test Library Architecture Framework )
測試庫構架框架的核心思想可以概括為系統功能操作和業務邏輯的解耦。將所有的針對測試系統支持的功能操作封裝在測試庫中,測試腳本調用測試庫的同時傳遞外部的測試數據,測試庫的編寫由自動化測試發工程編寫(可以不懂業務),負責控制項的變更和維護, 測試腳本的編寫可由對業務比較掌握的自動化測試開發工程編寫,負責業務邏輯、測試數據的變更和維護。
優點:被測試系統無論是哪層發生變化(代碼層或業務層等),只需要相應的人員進行變更維護即可。
缺點:變更引起的維護工作同時附加在自動化測試開發工程師與業務測試人員身上,維護代碼建級大。
適應場景:基於各種自動化開展方式(基於工具如Jemet或不基於工具的自研研發+持續集成)一般都會應用該框架。
數據驅動的自動化測試框架( The Data-Driven Testing Framework )
數據驅動的核心思想可以概括為數據(測試數據、配置數據)與代碼解耦。該種框架的原理是採用了數據驅動腳本進行測試,數據驅動腳本是將數據輸入存儲在獨立的數據文件中,腳本只存代碼,運行時腳本的輸入直接從文件中讀取,如此相同的腳本(代碼模版)可以運行於不同的測試用例中,實現了代碼與數據的分離。
優點:對於業務人員由面向代碼的開發轉換為面向配置的設計(參數組合設計), 降低了開發難度與開發成本,同時提高了測試用例的易擴展性,可以快速擴展相似測試,實現了自動化代碼不隨用例的增長而增
缺點:測試腳本的維護由自動化測試開發工程師負責,要求懂自動化編程和業務邏輯,初始測試腳本設計成本較大,具有一定局限性 (針對相同的測試內容並具有相同的測試邏輯).
適用場景:更適應於測試內容測試邏相重復度高,被測對象對測試用例易擴展性、可復用性要求較高的場景。
關鍵字或表驅動的自動化測試框架(The Keyword-Driven or Table-Driven Testing Framework )
關鍵字驅動是對數據驅動的邏相擴展,它的核心思想可以概括為數據代碼流程(邏輯)解耦,同時完成了代碼與測試描述(針對被測對象的測試描述)的映射。該框架的原理是基於數據驅動的基礎上,完成了對被測對象的拆分、抽象、 封裝使之映射成個個「關鍵詞」 (測試描述),編寫測試用例時,僅需要對關鍵詞進行組合 ,即可完成不同場景的測試用例開發。
優點:對於業務手工測試人員,由面向代碼或配置的開發轉化為面向自然語言(測試描述)的開發,最大程度的降低了開發難度與維護成本,同時提高了測試用例的易擴展性、易組織性,實現了自動化代碼不隨用例的增長而增多。
缺點:對測試人員的測試開發能力以及業務了解程度要求很高。
適用場景:被測對象包含復雜業務流程(邏輯),當然復雜的能做簡單的更ok。
了解 更多可以看著這篇文章,希望對你有所幫助,歡迎關注、點贊支持。
https://www.toutiao.com/i6616242076721873416/
Ⅶ python的特性是什麼
Python是一門大家都比較熟悉的一門計算機語言,也是比較簡單的一門計算機語言,相對於來說更加簡單一些,而且也是不少人進入行業內的首要選擇。
Python是一門好用又簡單易學的計算機編程語言,在近幾年中,Python受到了不少IT人士的追捧,熱度也是越來越高了,成為了我們入門首選的編程語言,為什麼呢?因為Python具有非常廣泛的應用范圍,在人工智慧、web開發之中具有非常好的應用,同時在金融分析、爬蟲等領域也具有很大的作用。
1、Python採用C語言進行開發,但是Python不再有C語言中的指針等復雜的數據類型存在。
2、Python具有很強的面向對象特性,同時也簡單化了面向對象的實現,可以消除保護類型、抽象類、介面等面向對象的元素。
3、Python代碼可以使用空格或者製表符縮進的方式分割代碼。
4、Python僅僅只有31個保留字,而且沒有分號、begin、end等標記。
5、Python是強類型的語言,變數創建之後會對應一種數據類型,出現在統一表達式中的不同類型的變數需要做類型轉換。