Python全棧工程師(多繼承、函式重寫)
Python人工智慧從入門到精通
補充:
物件 -------------------------> 類
例項變數(屬性) 類變數
例項方法 類方法( @classmethond)
靜態方法( @staticmethond)(類內普通函式)
繼承/派生
單繼承:
一個子類只有一個父類
一個父類可以有多個子類
--------------------------------------------------------------------------------------------
用於類的函式:
issublclass(cls, cls_or_tuple)
判斷這個類是否繼承自其他類, 如果此cls是class
或tuple中的一個派生子類, 返回True 否則返回False
示例:
class A:
pass
class B(A):
pass
class C(B):
pass
issublclass(C, B) # True
issublclass(B, C) # False
issublclass(C, (int, str)) # False
issublclass(C, (int, B, str)) # True
封裝 enclosure
封裝是指隱藏類的實現細節,讓使用者不關心這些細節
封裝的目的是讓使用者通過儘可能少的方法(或屬性)操作物件
私有屬性和私有方法:
python類中以雙下劃線(__)開頭,
不以雙下劃線結尾的識別符號為私有成員,私有成員或只能用類的方法進行訪問和修改
以__開頭的例項變數有私有屬性
以__開頭的方法有私有方法
示例:
class A: def __init__(self): self.__p1 = 100 # 私有屬性 def show_A(self): print("self.__p1", self.__p1) self.__m1() # 可以呼叫自己的方法 def __m1(self): # 私有方法 print("__m1(self)方法被呼叫") a = A() a.show_A() # 100 # print(a.__p1) # 出錯 不能在類外部訪問a.__p1私有屬性 也不能在子類中訪問 # a.__m1() # 出錯 不能在類外部訪問a.__p1私有方法 也不能在子類中訪問 class B(A): pass b = B() print(b.__p1) # 出錯,子類不能訪問父類的私有成員 b.__m1() # 出錯 b._A__p1 = 200 # python的假封裝可以用此方法訪問 print(b.__p1) # 200
多型polymorphic:
什麼是多型
就是多種狀態
多型是指在繼承/派生關係的類中,呼叫基類物件的方法,
實際能夠呼叫子類的覆蓋方法的現象叫多型
狀態:
靜態(編譯時狀態)執行速度快
動態(執行時狀態)執行速度慢
說明:
多型呼叫方法與物件相關,不與類相關
Python的全部物件只有“執行時狀態(動態)”
沒有C++語言裡的“編譯時狀態(靜態)”
由於Python是解釋執行的 是動態 沒有靜態
是在執行時編譯(解釋執行)
示例:
# Pytgon中的執行時狀態 class Shape: def draw(self): print("Shape的 draw 方法被呼叫") class Point(Shape): def draw(self): print("畫車") class Circle(Shape): def draw(self): print("畫圈") # python無法實現靜態 除非不出現任何覆蓋 def my_draw(s): # 其他靜態語言 def my_draw(Circle s) 指定呼叫者 無法進行改變 s.draw() # 此處顯示出"動態" s1 = Circle() s2 = Point() my_draw(s1) # 只有在呼叫時才能能確定呼叫哪一個 my_draw(s2)
面向物件不是程式設計而是一種思想
面向物件的語言的特徵:
繼承
封裝
多型
多繼承:multiple inheritance
多繼承是指一個子類繼承自兩個或兩個以上的基類
語法:
class 類名(基類名1, 基類名2, ...)
說明:
1.一個子類同時繼承自多個父類,父類中的方法可以同時被繼承下來
2.如果兩個父類中同時有同名方法,而在子類中又沒有覆蓋此方法時,
呼叫結果難以確定 (也可以確定 C3演算法)
示例:
class Car: def run(self, speed): print("汽車", speed, "Km/h 的速度行駛") class Plane: def fly(self, height): print("飛機以海拔", height, "米高度飛行") class PlaneCar(Plane, Car): '''同時繼承Plane,Car的方法''' p1 = PlaneCar() p1.fly(10000) p1.run(300)
多繼承的問題(缺陷):
識別符號衝突的問題
要謹慎使用繼承
示例:
# 多繼承名字衝突問題 class A: def m(self): print("A.m被呼叫") class B: def m(self): print("B.m被呼叫") class AB(A, B): # 優先呼叫先出現的父類 有先後順序 pass ab = AB() ab.m() # A.m被呼叫 class BA(B, A): pass ba = BA() ba.m() # B.m被呼叫
多繼承的MRO(Method Resolution Order):
類的__mro__屬性
__mro__ 是一個元組 裡面存放類
此屬性用來記錄方法查詢順序
示例:
class A: def go(self): print("A") class B(A): def go(self): print("B") class C(A): def go(self): print("C") class D(B, C): def go(self): print("D") super().go() d = D() d.go() # B # 多繼承的super呼叫關係一定是mro元組內的下一個類 和子父類沒關係 # 如果沒有方法則報錯 呼叫演算法(C3演算法) # 正常呼叫也是mro順序
函式重寫:
在自定義類內新增相應的方法,讓自定義類建立的例項
能像內建物件一樣進行內建函式操作
物件轉字串函式:
repr(obj) 返回一個能代表此物件的表示式字串,通常eval(repr(obj))== obj
(這個字串通常給Python解釋執行器執行用的)
str(obj) 返回的字串(這個字串通常給人閱讀用的)
物件轉字串函式的重寫方法:
repr(obj) 函式的重寫方法:
def __repr__(self):
pass
str(obj) 函式的重寫方法:
def __str__(self):
pass
說明:
1.str(obj)函式先查詢, obj.str()方法
呼叫此方法並返回結果
2.如果沒有obj.__str__方法時,返回obj.__repr__()
方法的結果並返回
3.如果obj.__repr__方法不存在,則呼叫obj類的__repr__
例項方法顯示:<__main__.XXXX object at 0x7f4b1c36fa90>
示例:
class MyNumber: def __init__(self, value): '建構函式,初始化MyNumber' self.data = value def __str__(self): '''轉換為人能夠識別的字串''' print("__str__方法被呼叫") return "自定義數字型別物件:%d" % self.data def __repr__(self): '''轉換為eval能夠識別的字串''' return 'MyNumber(%d)' % self.data n1 = MyNumber(100) n2 = MyNumber(200) print("repr(n1):--->", repr(n1)) print("strr(n2):--->", str(n2)) print("strr(n2):--->", n2.__str__())
其他內建函式的重寫方法:
__abs__ abs(obj) 函式
__len__ len(obj) 函式(必須返回整數)
__reversed__ reversed(obj) 函式(必須返回可迭代物件)
__round__ round(obj) 函式
示例:
# 函式重寫 class MyNumber: def __init__(self, v): self.data = v def __repr__(self): return 'MyNumber(%d)' % self.data def __abs__(self): '''__abs__函式重寫 求絕對值函式''' # return -self.data v = abs(self.data) return MyNumber(v) # 建立一個新的MyNumber物件 def __len__(self): '''__len__函式重寫 求長度函式''' # return len(self.data) i = 0 for x in self.data: i += 1 return i i1 = MyNumber(-10) print(i1) i2 = abs(i1) print(i2) i3 = MyNumber("123d5sa") print(len(i3))
資料轉換函式的重寫:
__complex__ complex(obj) 函式
__int__ int(obj) 函式
__float__ float(obj) 函式
__bool__ bool(obj) 函式
示例:
資料轉換建構函式重寫 class MyNumber: def __init__(self, v): self.data = v def __repr__(self): return 'MyNumber(%d)' % self.data def __int__(self): # return 999999 # 可以自定義返回規則 return self.data n1 = MyNumber(100) x = int(n1) print(type(x)) # <class 'int'> print(bool(n1)) # True n2 = MyNumber(0) print(bool(n2)) # True # 預設返回 # True
布林測試函式重寫:
格式:
__bool__
作用:
用於bool(obj)函式取值
用於if語句的真值表達式中
說明:
1.當自定義的類內有__bool__(self)
方法時,此方法的返回值為bool(obj)的返回值
2.當不存在__bool__(self),bool(x)
返回__len__(self)方法的返回值是否為零來測試布林值
3.當不存在__len__方法時,則直接返回True
示例:
# bool(x)函式重寫 class MyList: '''自定義型別的列表,用來儲存資料,內部用列表來儲存資料''' def __init__(self, iterable): self.data = [x for x in iterable] def __repr__(self): return " MyList(%s)" % self.data def __len__(self): '''返回長度''' print("__bool__方法被呼叫") return len(self.data) # def __bool__(self): # print("__bool__方法被呼叫") # return False # 此處定義所有物件返回False def __bool__(self): print("__bool__方法被呼叫") for x in self.data: if not x: return False return True # 自定義返回規則(這就是函式重寫) myl = MyList((1, 2, -3, 4, -5, 5)) print(myl) print(bool(myl)) if myl: print("myl是真值") else: print("myl是假值")
迭代器(高階):
什麼是迭代器:
可以通過next(it)函式取值的物件就是迭代器
迭代器協議:
迭代器是指物件能夠使用next函式獲取下一項資料,
在沒有下一項資料時觸發一個StopIteration異常來終止迭代的重寫
迭代器協議實現方法:
__next__(self) 方法來實現迭代協議
語法形式:
class MyIterator:
def __next__(self):
迭代器協議
return 資料
什麼是可迭代物件:
是指用 iter(obj) 函式返回迭代物件(例項)
可迭代物件內部需要定義__iter__(self)方法來返回迭代器物件
# 此示例示意讓自定義的作為可迭代物件能讓 for 語句迭代訪問 class MyList: '''建立MyList類''' def __init__(self, iterable=()): '''初始化self iterable:可迭代物件 ''' # 用iterable生成列表 self.data = [x for x in iterable] def __repr__(self): '''返回一個MyList字串''' return 'MyList(%s)' % self.data def __iter__(self): '''此方法必須返回一個迭代器物件 此方法建立一個迭代器物件並返回 ''' return MyListIterator(self.data) class MyListIterator: '''此類用來建立迭代器,此型別的迭代器可以迭代訪問 MyList型別的物件''' def __init__(self, lst): self.data = lst self.cur_index = 0 # 初始化迭代器的起始位置 def __next__(self): '''此方法用於實現迭代器協議''' if self.cur_index >= len(self.data): # 如果索引越界就發終止迭代通知 raise StopIteration value = self.data[self.cur_index] # 要返回的值 self.cur_index += 1 return value myl = MyList([0, -1, 2, -3]) print(myl) # it = iter(myl) # print(next(it)) for x in myl: # 迭代訪問自定義型別的可迭代物件 print(x)
練習:
寫一個類Bicycle類 ,有 run方法.呼叫時顯示騎行里程km
class Bicycle:
def run(self, km):
print('自行車騎行了', km, '公里')
再寫一個類EBicycle(電動自行車類), 在Bicycle類的基礎上添加了電池電量 volume 屬性, 有兩個方法:
1. fill_charge(self, vol) 用來充電, vol為電量
2. run(self, km) 方法每騎行10km消耗電量1度,同時顯示當前電量,當電量耗盡時呼叫 父類的run方法繼續騎行
b = EBicycle(5) # 新買的電動有內有5度電
b.run(10) # 電動騎行了10km還剩 4 度電
b.run(100) #電動騎行了40km,還剩0度電,其餘60用腳登騎行
b.fill_charge(10) # 又充了10度電
b.run(50) # 騎行了50公里剩5度電
答案:
class Bycycle: def run(self, km): '''自行車''' print("自行車騎行了", km, "公里") class EBycyle(Bycycle): def __init__(self, volume=0): '''初始化電動車''' self.volume = volume print("新買的電動車有", volume, "度電") def fill_charge(self, vol): '''衝電''' self.volume += vol print("又衝了", vol, "度電") def run(self, km): self.volume -= (km / 10) # 減去使用的電量 x = abs(self.volume) * 10 # 計算超出的公里 if self.volume < 0: # 判斷是否超出電量 self.volume = 0 print("電動車騎行了", km, "千米 還剩", self.volume, "度電 其餘", x, "千米用腳蹬") else: print("電動車騎行了", km, "千米 還剩", self.volume, "度電") b = EBycyle(10) b.run(10) b.run(100) b.fill_charge(10) b.run(50) # 新買的電動車有 10 度電 # 電動車騎行了 10 千米 還剩 9.0 度電 # 電動車騎行了 100 千米 還剩 0 度電 其餘 10.0 千米用腳蹬 # 又衝了 10 度電 # 電動車騎行了 50 千米 還剩 5.0 度電 b = EBycyle(50) b.run(10) b.run(100) b.fill_charge(10) b.run(50) # 新買的電動車有 50 度電 # 電動車騎行了 10 千米 還剩 49.0 度電 # 電動車騎行了 100 千米 還剩 39.0 度電 # 又衝了 10 度電 # 電動車騎行了 50 千米 還剩 44.0 度電
練習:
1. 修改原有的學生資訊管理系統, 將學生物件的,全部屬性
都變為私有屬性,不讓外部直接訪問來實現封裝
原始碼:
https://pan.baidu.com/s/1szQDS5cfzVHLlZrrJcCs8A
2. 寫一個列表類MyList實現儲存整數列表,寫類的定義如下:
class MyList:
def __init__(self, iterator):
self.data = ...
讓此類的物件能用for語句進行迭代訪問
L = MyList(range(5))
print(L)
L2 = [x ** 2 for x in L]
print(L2) # [0, 1, 4, 9, 16]
答案:
class MyList: def __init__(self, iterable=()): self.lst = [x for x in iterable] def __repr__(self): return "%s" % self.lst def __iter__(self): return MyIterable(self.lst) class MyIterable: def __init__(self, lst): self.lst = lst self.myindex = 0 def __next__(self): if self.myindex >= len(self.lst): raise StopIteration value = self.lst[self.myindex] self.myindex += 1 return value L = MyList(range(5)) print(L) for x in L: print(x) L2 = [x ** 2 for x in L] print(L2)
3. 寫一個類Fibonacci 實現迭代器協議 ,此類的物件可以作為可迭代物件生成相應的斐波那契數
1 1 2 3 5
class Fibonacci:
def __init__(self, n) # n代表資料的個數
...
...
實現如下操作:
for x in Fibonacci(10):
print(x) # 1 1 3 5 8 ....
L = [x for x in Fibonacii(50)]
print(L)
F = fibonicci(30)
print(sum(F))
答案:
直接繼承第二題的類
class Fibonicci(MyList): def __init__(self, n): L = [1, 1] for _ in range(n - 2): L.append(L[-1] + L[-2]) self.lst = L for x in Fibonicci(10): print(x) # 1 1 3 5 8 .... L = [x for x in Fibonicci(50)] print(L) F = Fibonicci(30) print(F) print(sum(F))
相關推薦
Python全棧工程師(多繼承、函式重寫)
ParisGabriel 每天堅持手寫 一天一篇 決定堅持幾年 為了夢想為了信仰 開局一張圖 Python人工智慧從入門到精通 補充: 物件 -------------------------> 類例項變數(屬性
Python全棧工程師(42:Web框架Django步驟)
1.建立Django工程django-admin startproject 工程名2.建立appcd 工程名python manage.py startapp cmdb3.靜態檔案project.settings.pySTATICFILES_DIRS = (
Python:封裝、多型、多繼承、函式重寫、布林測試函式重寫、迭代器(高階)
用於類的函式: issubclass(cls,class_or_tuple)判斷一個類是否繼承自某個類class或某類tuple中的 一個類,如果是則返回true,否則返回false 示例: class A: pass cla
Python全棧工程師(32:Dom)
文件物件模型(Document Object Model,DOM)是一種用於HTML和XML文件的程式設計介面。它給文件提供了一種結構化的表示方法,可以改變文件的內容和呈現方式。DOM把網頁和指令碼以及其他的程式語言聯絡了起來。DOM屬於瀏覽器,而不是JavaScript語言
python全棧測試題(一)
span hello sdi 執行 python腳本 pan 數字 ice 登錄 1、執行Python腳本的兩種方式 如果想要永久保存代碼,就要用文件的方式 如果想要調試代碼,就要用交互式的方式即終端命令下和python環境中 2、Pyhton單行註釋和多行註釋分別用什
Python全棧day9(Python基礎)
lin 終端 .exe linux efi 雙擊 config 編譯 tps Python基礎 一,Windows安裝Python3.5 下載地址:https://www.python.org/ftp/python/3.5.2/python-3.5.2rc1-amd64.e
Python全棧day13(作業講解字典嵌套實現用戶輸入添加及查看)
語句 地址 技術 list 輸入 ima 北京 ice lower 要求: 列出字典對應節點名稱,根據用戶輸入可以添加節點,查看節點等功能,這裏以地址省-市-縣等作為列子,此題熟悉字典嵌套功能 vim day13-16.py db = {} path = [] wh
Python全棧day14(字符串格式化)
obb per 用途 轉換 clas 接受 應輸入 ber 打印 一,%字符串格式化 1,使用%s 後面一一對應輸入對應的字符串,%s可以接受任何參數 print ("I am %s hobby is zhangsan"%‘lishi‘) print ("I am
Python全棧day18(叠代器協議和for循環工作機制)
內部 highlight next 計算 內置函數 如何 異常 初始 一次循環 一,什麽是叠代和遞歸 遞歸和叠代都是循環的一種。 簡單地說,遞歸是重復調用函數自身實現循環。叠代是函數內某段代碼實現循環,而叠代與普通循環的區別是:循環代碼中參與運算的變量同時是保存結果
Python全棧day18(三元運算,列表解析,生成器表達式)
協議 什麽是 list 列表解析 不但 pri 就是 雞蛋 無限制 一,什麽是生成器 可以理解為一種數據類型,這種數據類型自動實現了叠代器協議(其他數據類型需要調用自己內置的__iter__方法),所以生成器是可叠代對象。 二,生成器分類在python中的表現形式
Python全棧day21(調用模塊路徑BASEDIR的正確方法)
變化 一個 pre dirname 發生 文件 導入 復制 sys 正常寫python程序會有一個可執行的bin.py文件,假如這個文件需要導入my_module裏面定義的模塊,應該怎麽設置sys.path 文件夾目錄結構如下,因為bin不在與my_module同級目錄下,
python全棧開發-Day2 布爾、流程控制、循環
class 用戶輸入 體重 命令 外部 表達 pan ger pre python全棧開發-Day2 布爾 流程控制 循環 一、布爾 1、概述 #布爾值,一個True一個False #計算機俗稱電腦,即我們編寫程序讓計算機運行時,應該是讓計算機無限接近人腦,或者說人
Python全棧__叠代器、生成器、知識點補充、列表推導式,生成器表達式、如何系統科學的學習Python
ide swa XP iter count CA slow iterable 就是 1、叠代器 (1)可叠代對象 1 s1 = ‘123‘ 2 for i in s1: 3 print(i) 可叠代對象 示例結果: D:
2018-07-04-Python全棧開發day25-靜態屬性、類方法、靜態方法以及組合
之前 cls school 直觀 imp 學校 int nba while 1.靜態屬性property 作用:改變類中方法的調用方式,不需要加括號,看起來和數據屬性的調用方式相同 class Fangjian(): tag=‘888‘ def
最全python全棧工程師視頻教程
http 教程 read for 網盤 blog 最全 全棧工程師 圖片 下載地址:百度網盤最全python全棧工程師視頻教程
Python全棧__動態參數、名稱空間、作用域、作用域鏈、加載順序、函數的嵌套、global、nonlocal
sharp 空間 Python全棧 highlight 參數 int() 相等 lex 動態參數 1、動態參數 當實參數量與形參數量相等時,參數傳遞正常。 def func1(a, b, c): pass func1(1, 2, 3)
web全棧工程師(前端進階)學習線路圖
近兩年關於“前端工程師堅守前端還是主攻全棧開發”的問題,成為很多程式設計愛好者熱議的話題。全棧開發工程師的概念最早是由Facebook提出的。全棧的核心是指開發者能夠承擔包括前端、後端在內的所有功能開發任務。與傳統前端相比,web全棧開發工程師需要具備跨領域知識,甚至需要成為全才。作為勇於挑戰自我的前端,
前端程式設計師如何快速轉型全棧工程師(基礎版)
前端與後端的思維專注點很不相同,前端聚焦在如何把內容以視覺化的方式展現給使用者,後端聚焦在如何利用IT基礎設施實現業務邏輯。所以前端參與後端開發時(全棧工程師必備!)首先需要理解後端會做哪些事,其次才是如何才能做好這些事。 所謂“利用IT基礎設施實現業務邏輯”,意味著以下幾
Python全棧工程師學習筆記|Django框架介紹與安裝
Python全棧工程師學習筆記|Django框架介紹與安裝 (1). Web開發介紹 進群:943752371可以獲取Python入門學習資料哦! Python全棧工程師學習筆記|Django框架介紹與安裝 目前Web開發屬於Browser/Server模式,簡稱B
Python全棧工程師學習筆記|Django框架介紹與安裝!
wrap tle 無需 基礎設施 nag 當前 不同 shadow var (1). Web開發介紹 目前Web開發屬於Browser/Server模式,簡稱BS架構,開發語言有(Python、PHP、Java ...)。基於Python的Web工作原理如下:(2). 框架