Three---面向對象與面向過程/屬性和變數/關於self/一些魔法方法的使用/繼承/super方法/多態

来源:https://www.cnblogs.com/311dih/archive/2022/08/13/16583840.html
-Advertisement-
Play Games

python的面向對象 面向對象與面向過程 面向過程 面向過程思想:需要實現一個功能的時候,看重的是開發的步驟和過程,每一個步驟都需要自己親力親為,需要自己編寫代碼(自己來做) 面向對象 面向對象的三大特征:封裝性、繼承性、多態性 面向對象思想:需要實現一個功能的時候,看重的並不是過程和步驟,而是關 ...


python的面向對象

面向對象與面向過程

面向過程

  • 面向過程思想:需要實現一個功能的時候,看重的是開發的步驟和過程,每一個步驟都需要自己親力親為,需要自己編寫代碼(自己來做)

面向對象

  • 面向對象的三大特征:封裝性、繼承性、多態性
  • 面向對象思想:需要實現一個功能的時候,看重的並不是過程和步驟,而是關心誰幫我做這件事(偷懶,找人幫我做)

類與對象

  • 對象是面向對象編程的核心,在使用對象的過程中,為了將具有共同特征和行為的一組對象抽象定義,提出了另一個新的概念——類
  • 類:抽象的,是一張“手機設計圖”
  • 對象:具體的,是一個“真正的手機實例”
  • 類是抽象的,在使用的時候通常會找到這個類的一個具體的存在;一個類可以找到多個對象
#學生案例
class Student():   #創建一個學生類
    #定義一個info函數,並傳參至self本身
    def info(self,name,age,sex):   
        print('學生的姓名是:',self.name)
        print('學生的年齡是:',self.age)
        print('學生的性別是:',self.sex)

yinianji = Student()   #創建一個具體的對象:一年級
yinianji.info()   #實例化對象調用定義的info函數

案例

當創建一個對象時,就是用一個模子來製造一個實物

#案例
class Dog():   #定義一個類的形式

    #info是一個實例方法,類對象可以調用實例方法,實例方法的第一個參數一定是self

    def info(self):
    
    #當對象調用實例化方法時,python會自動將對象本身的引用作為參數,傳遞到實例方法的第一個參數self裡面
        print(self)
        print("狗祖宗")

#Dog這個類實例化了一個對象 jinmao
jinmao = Dog()

#對象調用實例化方法info(),執行info()中封裝的代碼 .表示選擇屬性或方法
jinmao.info()

#列印對象,則預設列印對象在記憶體中的地址,結果等同於info中的print(self)
print(jinmao)

#id(taidamier)則時記憶體地址的十進位形式表示
print(id(jinmao))
-----------------------------------------------------------
<__main__.Dog object at 0x00000190A9DC67F0>
狗祖宗
<__main__.Dog object at 0x00000190A9DC67F0>
1720836712432

屬性和變數

屬性和變數的區別

  1. 屬性:指某個對象的具體特性
  2. 變數:指可以更改的量

屬性和變數的判斷依據

  • 根據宿主判斷:變數無宿主,屬性有宿主
  • 根據宿主的不同又分為對象屬性以及類屬性

對象屬性獲取

  • 對象既然有實例方法,也可以有自己的屬性
  • 在方法內通過self獲取對象屬性
#對象屬性獲取
class Dog():   #定義一個狗類

    def move(self):    #移動實例方法
        print("moving...")

    def attack(self):   #咬人實例方法
        print("咬人")

#實例化一個狗對象 jinmao
jinmao = Dog()

#給對象添加屬性,以及對應的屬性值
jinmao.name = "xiao"
jinmao.hp = 200
jinmao.atk = 40
jinmao.armor = 100

#通過.成員選擇運算符,獲取對象的屬性值
print("%s 的生命值為:%d" %(jinmao.name,jinmao.hp))
print("%s 的攻擊力為:%d" %(jinmao.name,jinmao.atk))
print("%s 的護甲值為:%d" %(jinmao.name,jinmao.armor))

#通過.成員選擇運算符,獲取對象的實例方法
jinmao.move()
jinmao.attack()
-----------------------------------------------------------
xiao 的生命值為:200
xiao 的攻擊力為:40
xiao 的護甲值為:100
moving...
咬人

關於self

  • self就是實例化對象本身
#關於self
class A:
    def f(self,data):
        print(self.name)
        print(data)

o = A()

print(A.f)
print(o.f)
-----------------------------------------------------------
<function A.f at 0x000002725D28ADC0>
<bound method A.f of <__main__.A object at 0x000002725D2467F0>>
  • 其中A.f對應的時function 即為一個普通的函數
  • o.f為bound method 即在函數上綁定了一個對象 —— o
  • 結論:o.f 是返回了一個method object ,而當去調用這個object時,他會記住被創建時綁定的對象,即返回該對象,預設參數為self

魔法方法

魔法方法__init__()

__init__方法可以在創建對象時就擁有一些屬性,__init__通常用來做屬性初始化 或 賦值 操作

  • 如果類沒有寫__init__方法,python會自動創建,但不會執行任何操作
  • 所以一個類里無論自己是否編寫__init__方法 都一定有__init__方法
案例一
#init方法
class Dog():
#方法,用來做變數初始化 或 賦值 操作,在類實例化對象的時候,會被自動調用
    def __init__(self,name,hp) -> None:
        #__init__方法也可以帶參數
        self.name = name
        self.hp = hp
        print(self.name,self.hp)

#實例化一個對象,並自動調用__init__方法
xiaohuang = Dog("小黃",200)
---------------------------------------------------------
class Dog():

    def f(self,name,hp):
        self.name = name
        self.hp = hp
        print(self.name,self.hp)
        
xiaohuang = Dog()
xiaohuang.f("小黃",200)
案例二
#init方法二
class Dog():
    
    def __init__(self,name,skill,hp) -> None:
        
        self.name = name
        self.skill = skill
        self.hp = hp
        
    def move(self):
        print("%s 正在前往事發地點..." % self.name)

    def attack(self):
        print("%s 咬人 %s..."%(self.name,self.skill))

    def info(self):
        print("%s 的生命值:%d"%(self.name,self.hp))

#實例化對象時,參數會傳遞到對象的__init__()方法中
jinmao = Dog("金毛","連環咬",200)
hashiqi = Dog("哈士奇","不鬆口",300)

#直接輸出對象即為地址
print(jinmao)
print(hashiqi)

#不同對象的屬性值的單獨保存
print(id(jinmao.name))
print(id(hashiqi.name))

#同一個類的不同對象,實例方法共用
print(id(jinmao.attack))
print(id(hashiqi.attack))
-----------------------------------------------------------
<__main__.Dog object at 0x000001A3209367F0>
<__main__.Dog object at 0x000001A32089F250>
1800138028976
1800138029168
1800131850880
1800131850880

總結

  • 在類內部獲取 屬性 和 實例方法,通過self獲取
  • 在類外部獲取 屬性 和 實例方法,通過對象名獲取
  • 如果有一個類有多個對象,每個對象的屬性時各自保存的,都有各自獨立的地址
  • 實例方法時所有對象共用的,只占用一份記憶體空間
  • 類會通過self來判斷是哪個對象,調用了實例方法

魔法方法__str__()

該方法用來顯示信息,通過一個字元串來描述實例對象,該方法需要return一個數據,並且只有self一個參數,在類的外部時用print(對象)列印這個數據(面向用戶)

#str方法
class Person():

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __str__(self):

        return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)

p1 = Person("李四",18)

P2 = Person("王五",19)

print(p1)
print(P2)
-------------------------------------------------------------
此人姓名為李四,此人的年齡為18
此人姓名為王五,此人的年齡為19
觸發方式:
1、直接通過print函數去列印
2、通過出發str函數進行轉換

魔法方法__repr__()

通過一個字元串描述實例對象的信息(面向開發人員)

#repr方法
class Person():

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __str__(self):

        return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)

p1 = Person("李四",18)

P2 = Person("王五",19)

print(repr(p1))
print(P2)
-------------------------------------------------------------
<__main__.Person object at 0x000001E7D9FD67F0>
此人姓名為王五,此人的年齡為19
#修改repr值
class Person():

    def __init__(self,name,age):

        self.name = name

        self.age = age

    def __str__(self):

        return "此人姓名為%s,此人的年齡為%s"%(self.name,self.age)

    def __repr__(self):   #更改repr參數值

        return "self"

p1 = Person("李四",18)

P2 = Person("王五",19)

print(repr(p1))
print(repr(P2))
print(P2)
-------------------------------------------------------------
self
self
此人姓名為王五,此人的年齡為19

repr與str

在輸出值時當存在str方法便會優先輸出str,repr可以面向開發者,同樣repr方法也可以作為一種方法去輸出str

#repr與str
import datetime

t = datetime.datetime.now()

print(t)   #此處輸出的為datetime庫中的類對應的str字元串

print(repr(t))   #同時輸出repr進行對比
-------------------------------------------------------------
2022-07-15 23:53:55.418332   #此為對應字元串輸出值

datetime.datetime(2022, 7, 15, 23, 53, 55, 418332)   #此為repr值
#通過eval函數輸出repr
import datetime

t = datetime.datetime.now()

print(t)   #此處輸出的為datetime庫中的類對應的str字元串

tmp = repr(t)

result = eval(tmp)   #使用eval函數執行輸出repr值的t

print(result)
-------------------------------------------------------------
2022-07-16 00:00:31.144619
2022-07-16 00:00:31.144619

魔法方法__del__()

創建對象後,python解釋器預設調用__init__()方法

當刪除一個對象時,python解釋器也會預設調用一個方法,這個方法叫__del__()

#del方法

class Dog():
    #創建對象後__init__方法會自動被調用
    def __init__(self, name):
        print("__init__方法被調用",name+"出生了")
        self.name = name

    #當對象執行完畢被刪除時,__del__方法會自動被調用
    def __del__(self):
        print("__del__方法被調用%s死了"%(self.name))


jinmao = Dog("金毛")
---------------------------------------------------------
__init__方法被調用 金毛出生了
__del__方法被調用金毛死了

繼承

  • 子類可以重寫父類的屬性和方法後,依然可以調用父類的屬性和方法
  • 使用super方法調用父類
  • 多層繼承關係同樣可以實現
  • 裝飾器
class Dog():   #創建父類Dog
    
    def __init__(self) -> None:
        self.name = "dog dad"
    def skill_dad1(self):
        print("attack people")

class Dog2():   #創建父類Dog2

    def __init__(self) -> None:
        self.name = "dog mom"
    def skill_mom1(self):
        print("attack dog")
    def skill_mom2(self):
        print("搖尾巴")

class Son(Dog,Dog2):   
#創建子類Son並繼承父類Dog和Dog2,繼承時優先繼承第一個父類Dog

    def __init__(self) -> None:
        self.name = "dog son"
    def skill(self):
        print("lick people")
    def dad_skill(self):    
        #通過super方法進行調用父類所定義的函數與方法
        super().__init__()   
        super().skill_dad1()
    def mom_skill(self):
        super().__init__()
        super().skill_mom1()
        super().skill_mom2()
    

jinmao = Son()
jinmao.dad_skill()
jinmao.mom_skill()
--------------------------------------------------------------
attack people
attack dog
搖尾巴

多態

  • 不同的子對象調用相同的父類放啊,產生不同的結果(繼承+重寫)
  • 一個父類可以擁有多個子類繼承
#多態
class Dog():
    def __init__(self) -> None:
        self.name = "dog mom"

    def skill(self):
        print("attack dog")

#子類/派生類
class Son1(Dog):
    def skill(self):
        print("attack man")

class Son2(Dog):
    def skill(self):
        print("attack woman")

class Son3(Dog):
    def skill(self):
        print("attack child")

#實例化
son1 = Son1().skill()
son2 = Son2().skill()
son3 = Son3().skill()
---------------------------------------------------------
attack man
attack woman
attack child

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 一、環境準備 1.資料庫 創建2個庫2個表: xdclass_shop_order_0 product_order_0 product_order_1 ad_config product_order_item_0 product_order_item_1 xdclass_shop_order_1 p ...
  • 1.什麼是序列化組件 在django中,自帶一個序列化組件,它是用來將數據進行整理、轉化成特定的為一個特定的格式(比如json數據格式),然後傳輸給前端,以便前端對數據進行處理操作。 2.為什麼要用序列化組件 當我們從資料庫取出一些數據時,我們需要將數據轉成特定的格式,比如列表套字典的形式,然後將這 ...
  • @(文章目錄) 提示:本文僅供學習交流,請勿用於非法活動! 前言 本文大概內容: 例如:隨著MongoDB的廣泛應用,電商用到MongoDB也越來越多。本文主要是在將購物車模塊切換到MongoDB框架前,如何快速將Mysql中購物車大批量訂單拷貝到MongoDB資料庫中? 一、原來代碼 如下,我們將 ...
  • 目錄 一.簡介 二.效果演示 三.源碼下載 四.猜你喜歡 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 基礎 零基礎 OpenGL (ES) 學習路線推薦 : OpenGL (ES) 學習目錄 >> OpenGL ES 轉場 零基礎 O ...
  • @(文章目錄) 提示:本文僅供學習交流,請勿用於非法活動! 前言 本文內容: 日誌搭建 一、依賴 <!-- Spring集成日誌包 --> <dependency> <groupId>ch.qos.logback</groupId> <artifactId>logback-classic</arti ...
  • 一、基本 1.hashmap: 1.1 轉紅黑樹條件: a.數組長度大於等於64(預設16,要經過2次擴容--當達到16*預設擴容因數0.75=12就擴容) b.鏈表長度大於8 1.2 hashmap先計算hash值,再用hash值計算下標。 2.sleep與await: 1.1 sleep是線程方 ...
  • @(文章目錄) 前言 一、建項目 1. 在父項目ams-cloud下建立maven子項目ams-websocket 2.pom文件添加常用依賴,另外添加redis依賴等,我這裡直接引用common模塊 <dependencies> <dependency> <groupId>com.alibaba. ...
  • 準備工作 概述:微信掃碼支付是商戶系統按微信支付協議生成支付二維碼,用戶再用微信掃一掃完成支付的模式。該模式適用於PC網站支付、實體店單品或訂單支付、媒體廣告支付等場景。 第一步:註冊公眾號(類型須為:服務號):請根據營業執照類型選擇以下主體註冊:個體工商戶| 企業/公司| 政府| 媒體| 其他類型 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...