1. 程式人生 > >Python全棧工程師(多繼承、函式重寫)

Python全棧工程師(多繼承、函式重寫)

ParisGabriel          每天堅持手寫  一天一篇  決定堅持幾年 為了夢想為了信仰   開局一張圖

                      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單行註釋和多行註釋分別用什

Pythonday9Python基礎

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

Pythonday13作業講解字典嵌套實現用戶輸入添加及查看

語句 地址 技術 list 輸入 ima 北京 ice lower 要求:   列出字典對應節點名稱,根據用戶輸入可以添加節點,查看節點等功能,這裏以地址省-市-縣等作為列子,此題熟悉字典嵌套功能 vim day13-16.py db = {} path = [] wh

Pythonday14字符串格式化

obb per 用途 轉換 clas 接受 應輸入 ber 打印 一,%字符串格式化   1,使用%s 後面一一對應輸入對應的字符串,%s可以接受任何參數 print ("I am %s hobby is zhangsan"%‘lishi‘) print ("I am

Pythonday18叠代器協議和for循環工作機制

內部 highlight next 計算 內置函數 如何 異常 初始 一次循環 一,什麽是叠代和遞歸   遞歸和叠代都是循環的一種。   簡單地說,遞歸是重復調用函數自身實現循環。叠代是函數內某段代碼實現循環,而叠代與普通循環的區別是:循環代碼中參與運算的變量同時是保存結果

Pythonday18三元運算,列表解析,生成器表達式

協議 什麽是 list 列表解析 不但 pri 就是 雞蛋 無限制 一,什麽是生成器   可以理解為一種數據類型,這種數據類型自動實現了叠代器協議(其他數據類型需要調用自己內置的__iter__方法),所以生成器是可叠代對象。 二,生成器分類在python中的表現形式

Pythonday21調用模塊路徑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__動態參數名稱空間作用域作用域鏈加載順序函數的嵌套globalnonlocal

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). 框架