Python基礎之面向對象:1、面向對象與編程思想

来源:https://www.cnblogs.com/kangssssh/archive/2022/11/02/16852630.html
-Advertisement-
Play Games

一、人狗大戰 1、需求 用代碼模擬人、狗打架的小游戲 人和狗種類不同,因此雙方的屬性各不相同 推導一: 人和狗各有不同屬性 使用字典方式儲存屬性較為方便,並可儲存多種屬性 # 1、在字典內儲存‘人’屬性 person = { 'name': '阿拉蕾', 'age': 18, 'gender': ' ...


一、人狗大戰

1、需求

  • 用代碼模擬人、狗打架的小游戲

  • 人和狗種類不同,因此雙方的屬性各不相同

image

推導一:

  • 人和狗各有不同屬性
  • 使用字典方式儲存屬性較為方便,並可儲存多種屬性
# 1、在字典內儲存‘人’屬性
person = {
     'name': '阿拉蕾',
     'age': 18,
     'gender': '女',
     'p_type': '戰士',
     'attack_val': 8000,
     'life_val': 99999999
 }

# 2、在字典內儲存‘狗’特有屬性
 dog1 = {
     'name': '小黑',
     'd_type': '泰迪',
     'attack_val': 100,
     'life_val': 8000
 }

推導二:

  • 按照上述方法,如果想要定義多個‘人’和‘狗’就需要反覆設置多個字典,這樣非常麻煩且費時
  • 這時可推導出,想要快速、便捷的定義多個‘人’和‘狗’,那麼我們可以把字典內的數據封裝在函數內,利用傳參的方式,這樣可以較為方便的生成多個‘人’和‘狗’,只需要使用不同變數名調用函數時傳不同的參數即可
# 1、封裝‘人’屬性函數
def create_person(name, age, gender, p_type, attack_val, life_val):
    person_dict = {
        'name': name,
        'age': age,
        'gender': gender,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return person_dict


# 2、封裝‘狗’屬性的函數
def create_dog(name, d_type, attack_val, life_val):
    dog_dict = {
        'name': name,
        'd_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val
    }
    return dog_dict


# 3、生成多個‘人’和‘狗’
p1 = create_person('阿拉蕾', 18, '男', '戰士', 8000, 99999999)
p2 = create_person('小朵朵', 28, '女', '法師', 100, 800)

d1 = create_dog('小黑', '泰迪', 100, 8000)
d2 = create_dog('小白', '鬥牛', 100, 800000)

推導三:

  • ‘人’和‘狗’就類似於各自不同種類的對象
  • 說到這裡,我們就應該明白,‘人’和‘狗’因為種類不同,所以雙方的屬性也各不相同,也就是說不同的對象,屬性(數據)各不相同
  • 當多個對象的屬性生成後,我們就要開始定義彼此打架的動作(功能)
    • 人打狗的動作
    • 狗咬人的動作
# 1、人打狗的動作
def person_attack(person_dict, dog_dict):
    print(f"{person_dict.get('name')}踢向{dog_dict.get('name')}")
    dog_dict['life_val'] -= person_dict.get('attack_val')
    print(f"人踢了狗一腳 狗掉血:{person_dict.get('attack_val')} 狗剩餘血量:{dog_dict.get('life_val')}")
    
# 2、狗打人的動作
def dog_attack(dog_dict, person_dict):
    print(f"{dog_dict.get('name')}向{person_dict.get('name')}咬去")
    person_dict['life_val'] -= dog_dict.get('attack_val')
    print(f"狗咬了人一口 人掉血:{dog_dict.get('attack_val')} 人剩餘血量:{person_dict.get('life_val')}")

# 3、調用雙方各自的函數,即可模擬出雙方打架的動作
person_attack(p1, d1)  # 人打狗
dog_attack(d2, p2)  # 狗咬人
-------------------------------------------------------
阿拉蕾踢向小黑
人踢了狗一腳 狗掉血:8000 狗剩餘血量:0
小白向小朵朵咬去
狗咬了人一口 人掉血:100 人剩餘血量:700

2、核心思路

  • ‘人’和‘狗’就是不同的對象
    • 通過將不同的屬性封裝在不同的函數內,就可以通過相同的函數快速生成不同屬性的對象
  • ‘人’和‘狗’打架的方式就是對象的功能
    • 人的打架方式是踢,狗的打架方式是咬,也就是說不同的類有著不同的功能,而相同的類就可以有著彼此相同的功能

需求:

  • 以上我們完成了不同種類的打架方式,但是在python中,如果沒有特別的限制,我們就可以把人攻擊的數據傳在狗攻擊函數內,這樣就會產生混亂,要如何實現下列需求
    • ‘人’只能調用人的攻擊方式
    • ‘狗’只能調用狗的攻擊方式

推導一:

"""推導步驟4:如何實現只有人只能調用的人的攻擊動作  狗只能調用狗的攻擊動作>>>:數據與功能的綁定"""
def get_person(name, age, gender, p_type, attack_val, life_val):
    # 產生人的函數(功能)
     def person_attack(person_dict, dog_dict):
        print(f"{person_dict.get('name')}踢向{dog_dict.get('name')}")
        dog_dict['life_val'] -= person_dict.get('attack_val')
        print(f"人踢了狗一腳 狗掉血:{person_dict.get('attack_val')} 狗剩餘血量:{dog_dict.get('life_val')}")
    # 表示人的信息(數據)
    person_dict = {
        'name': name,
        'age': age,
        'gender': gender,
        'p_type': p_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'person_attack': person_attack
    }
    return person_dict


def get_dog(name, d_type, attack_val, life_val):
    def dog_attack(dog_dict, person_dict):
        print(f"{dog_dict.get('name')}向{person_dict.get('name')}咬去")
        person_dict['life_val'] -= dog_dict.get('attack_val')
        print(f"狗咬了人一口 人掉血:{dog_dict.get('attack_val')} 人剩餘血量:{person_dict.get('life_val')}")
    dog_dict = {
        'name': name,
        'd_type': d_type,
        'attack_val': attack_val,
        'life_val': life_val,
        'dog_attack': dog_attack
    }
    return dog_dict


person1 = get_person('jason', 18, 'male', '猛男', 8000, 99999999)
dog1 = get_dog('小黑', '惡霸', 800, 900000)
person1.get('person_attack')(person1, dog1)

結論:

  • 通過上列代碼,我們將人的專屬攻擊方式,封裝在了人的類別內,實現了人專屬的屬性和功能,當人在調用自身類別,並傳入符合條件的參數時,就可以生成一個人(對象)特有的屬性(數據)和攻擊方式(功能)
  • 同上,我們也可將狗的數據和攻擊方式封裝在狗特有的函數內,當我們生成多條狗的時候,每條狗也就有了,狗(對象)特有的屬性(數據)和攻擊方式(功能)

人狗大戰推導就是面對對象的核心思想:數據與功能的綁定!!

二、編程思想

引言:

  •   面向對象是一種編程思想,用這種思想為指導設計的程式,把數據和對數據的操作封裝在一起組成類,通過類來創建對象,通過對象之間的交互來實現程式的功能。
    
  •    面向對象編程是一種編程方式,此編程方式的落地需要使用 “類” 和 “對象” 來實現,所以,面向對象編程其實就是對 “類” 和 “對象” 的使用
    

1、面向過程編程

  • 面向過程即流程
    • 在以上所學習的編程中,我們都是在按照固定的流程解決問題,制定一個結果,在奔向結果的過程中編寫代碼,以達到我們所需要的結果
    • 需要例舉出每一步流程 隨著流程的深入 結果慢慢浮現
      image

2、面向對象編程

  • 對象即容器,數據與功能的結合體 (python中一切皆對象)
    • 類似於開放式游戲,制定出游戲人物的(對象)
    • 該人物未來會如何發展,全看用戶如何控制,和我們程式員沒有關係
      • 類似於王者榮耀,玩家控制英雄走向
        image

上述兩種編程思想沒有優劣之分 需要結合實際需求而定
如果需求是註冊 登錄 人臉識別肯定面向過程更合適
如果需求是游戲人物肯定是面向對象更合適
實際編程兩種思想是彼此交融的 只不過占比不同

三、面向對象

1、類與對象

對象:

  • 數據與功能的結合體
  • 是由類創建出來的一個具體存在,可以直接使用;由哪一個類創建出來的對象,該對象就具有在那一個類中定義的屬性和方法

類:

  • 多個對象相同數據和功能的結合體
  • 是對一群具有相同特征或者行為的事物的一個統稱,不能直接使用;特征被稱為屬性;行為被稱為方法。
    image

2、類與對象的創建

現實中一般是先有對象再有類
程式中如果想要產生對象 必須要先定義出類

1.語法結構

class 類名:
	'''代碼註釋'''
	對象公共的數據
	對象公共的功能

1.class是定義類的關鍵字
2.類名幾乎和變數名一致,使用的時候推薦類名的首字母大寫
3.數據:
	變數名與數據值的綁定
  功能:
	功能(方法)其實就是具有一定功能的函數

2.定義與調用

需求:

  • 清華大學選課系統
'''	
類在定義階段就會執行類函數體代碼
但類的函數體代碼外界無法直接調用
'''

1、定義類
class Student:
    # 對象公共的數據
    school_name = '清華大學'
    
    # 對象公共的功能
    def choice_course(self):
        print('學生選課功能') 

查看類的名稱空間:

  • 在面向對象中,類和對象訪問數據或者功能,可以統一採用句點符
print(Student.__dict__) 
# {'__module__': '__main__', 'school_name': '清華大學', 'choice_course': <function Student.choice_course at 0x0000018FCCCD5670>, '__dict__': <attribute '__dict__' of 'Student' objects>, '__weakref__': <attribute '__weakref__' of 'Student' objects>, '__doc__': None}

print(Student.__dict__.get('school_name'))
# 清華大學

print(Student.__dict__ .get('choice_course'))
# <function Student.choice_course at 0x000001417B975670>

類的調用:

  • 類加括弧就會產生對象,並且每調用一次就會產生一個全新的對象
  • 變數名obj接收類名加括弧之後的返回值(結果)
1、調用對象
    obj1 = Student()  
    # <__main__.Student object at 0x000001992C2759D0> 
    obj2 = Student()
    # <__main__.Student object at 0x000001992C278E50>
    obj3 = Student()
    # <__main__.Student object at 0x000001992C278E20>
'''
三個變數名的地址各不相同,產生三個對象
 '''

2、查看對象內部數據
    print(obj1.__dict__,
        obj2.__dict__,
        obj3.__dict__)
    # {} {} {}
'''
三個對象各自內部都為空
 '''

3、調用對象共同數據
    print(obj1.school_name)
    # 清華大學
    print(obj2.school_name)
    # 清華大學
    print(obj3.school_name)
    # 清華大學
'''
同一類產生的對象,都可使用類內部公用數據值
'''

數據和功能可稱統稱為屬性:

  • 數據>>>屬性名

  • 功能>>>方法

3、對象獨有數據

​ 在上述使用類產生對象時,我們可以看出產生的對象並沒有自己特有的數據,針對如何給對象手動添加獨有數據,python提供了多種方式,其中前4種方式主要為推導第五種方式而來,我們只需簡單瞭解即可,在日後我們重點使用的是第五種方式

第一種:

  • 通過__ dict __ 加中括弧的方式
obj1.__dict__['name'] = 'jason'
obj1.__dict__['age'] = 18
obj1.__dict__['hobby'] = 'study'

第二種:

  • 將對象獨有的數據提前封裝成函數,在後續添加的時候,通過傳參的方式進行添加
def init(obj,name,age,hobby)
    obj.__dict__['name'] = name
    obj.__dict__['age'] = age
    obj.__dict__['hobby'] = hobby
    
init(ojb1.'kangkang', 18, 'read')
init(ojb2, 'zhangzhang', 28, 'ball')

第三種:

  • 將封裝數據的函數放在類的內部,只有相同類的對象才有資格使用
class Student:
    # 對象公用的數據
    school_name = '清華大學'

    # 專門給學生添加獨有數據的功能
    def init(obj, name, age, hobby):
        obj.__dict__['name'] = name
        obj.__dict__['age'] = age
        obj.__dict__['hobby'] = hobby
        # 對象公共的功能
	 def choice_course(self):
         print('學生選課功能')
            
            
stu1 = Student()
Student.init(stu1, 'kangkang', 18 , 'read')
Student.init(stu2, 'zhangzhang', 28 , 'ball')

第四種:

  • 將封裝獨有功能的函數名替換成__ init __ 這種方式,在我們給對象添加獨有功能時,可自動觸發
class Student:
    # 對象公用的數據
    school_name = '清華大學'

    # 專門給學生添加獨有數據的功能
    def __init__(obj, name, age, hobby):
        obj.__dict__['name'] = name
        obj.__dict__['age'] = age
        obj.__dict__['hobby'] = hobby
        # 對象公共的功能
	 def choice_course(self):
         print('學生選課功能')

stu1 = Student('kangkang', 18, 'read')
Stu2 = Student('zhangzhang', 28, 'ball')

第五種:

  • 封裝獨有數據的函數體的第一個參數位置修改為self

  • 在使用類產生對象時直接在類的括弧內填入獨有數據

  • 這種方式是我們日後使用類產生獨有數據對象的主要方式

class Student:
    # 對象公用的數據
    school_name = '清華大學'

    # 專門給學生添加獨有數據的功能
    def __init__(self, name, age, hobby):
        self.__dict__['name'] = name
        self.__dict__['age'] = age
        self.__dict__['hobby'] = hobby
        # 對象公共的功能
	 def choice_course(self):
         print('學生選課功能')

stu1 = Student('kangkang', 18, 'read')
stu1 = Student('zhangzhang', 18, 'ball')

4、對象獨有功能

​ 上述學習瞭如何給相同類對象添加獨有數據的方式,下麵我們要學習如何給對象添加獨有功能

思考:

  • 1、直接將功能函數體代碼定義在全局名稱空間種,那麼該功能函數就不對象獨有的功能
  • 2、將功能函數體代碼放在類中,但是類中的函數體功能,只要是此類產生的對象都可調用

解決方法:

  • 定義在類中的功能,預設就是給類產生的對象使用的,只要是此類產生的對象都可以使用
  • 需要在功能函數形參數內填入self,之後只需要用類名’點‘函數名的方式,函數參數內填入調用對象名,就可直接使用該功能
class Student:
    # 對象公用的數據
    school_name = '清華大學'

    # 專門給學生添加獨有數據的功能
    def __init__(self, name, age, hobby):
        self.__dict__['name'] = name
        self.__dict__['age'] = age
        self.__dict__['hobby'] = hobby
        # 對象公共的功能
	 def choice_course(self):
         print('學生選課功能')
            
stu1 = Student()
Student.choice_course(stu1)

5、補充知識

1、對象數據值修改

# 只需要使用對象‘點’的數據綁定的變數名的方式重新賦值即可
stu1.name = 'zhaozhao'

# 當名字不存在的情況下,將直接新增數據
stu1.paw = 123

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

-Advertisement-
Play Games
更多相關文章
  • 11月4日,華為開發者大會HDC2022在東莞松山湖拉開帷幕。HMS Core在本次大會上帶來了包括音頻編輯服務的高擬真歌聲合成技術、視頻編輯服務的智能提取精彩瞬間功能、3D Engine超大規模數字世界實時渲染技術,以及為聽障人群發聲的手語服務等HMS Core最新技術能力進展 。此外,HMS C ...
  • 好家伙,JS基礎接著學, 本篇內容為《JS高級程式設計》第四章學習筆記 1.原始值和引用值 ECMAScript變數可以包含兩種不同類型的數據:原始值和引用值。原始值(primitive value)就是最簡單的數據,引用值(reference value)則是由多個值構成的對象。 在把一個值賦給變 ...
  • 前言 這是疫情可視化最開始的文章,有需要瞭解的可前往查看:https://www.cnblogs.com/xi12/p/16690119.html。 本來說有時間就把這個項目完結了的,結果後面一直有事拖著,直到現在十一月份了才搞完。老樣子,先看成果。 瀏覽鏈接:https://xi1213.gite ...
  • call,apply,bind都是一種方法。 一,call() ①:call() 是可以 調用函數的。 1 function fn() { 2 console.log(12) 3 } 4 5 fn.call() // 12 ②:通過給call() 內部傳參,可以改變 this指向。 1 let Do ...
  • React 全家桶-React基礎 用於構建用戶界面的JavaScript庫。 facebook開源、組件化、聲明式編碼、React Native移動端開發、虛擬DOM+Diffing演算法 官網:https://react.docschina.org/ 第一章:React的基本使用 1.相關js庫 ...
  • 具體需求 在我的疫情可視化項目中有一個功能需要導出word文檔,在頁面點擊按鈕後處理數據生成word文件,然後自動下載文檔。 實現步驟 多番查詢後發現前端導出word,使用docxtemplater較為方便。具體使用步驟如下: 安裝docxtemplater:npm i docxtemplater ...
  • 導讀:對於錯誤碼的設計,不同的開發團隊有不同的風格習慣。本文分享阿裡文娛技術專家長統對於錯誤碼的看法,希望從錯誤碼使用的不同場景討論得到一個合理的錯誤碼規約,得到一個面嚮日志錯誤碼標準和一個面向外部傳遞的錯誤碼標準。 ...
  • 1、UML統一建模語言 定義:用於軟體系統設計與分析的語言工具 目的:幫助開發人員更好的梳理邏輯、思路 學習地址:UML概述_w3cschool 官網:https://www.omg.org/spec/UML 1.1、UML組成結構 flowchart TD; UML圖 --> 結構圖 & 行為圖; ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...