python——面向對象

来源:https://www.cnblogs.com/Wu-Ling/archive/2022/07/29/16528922.html
-Advertisement-
Play Games

編程思想: 面向過程:問題比較簡單,可以用線性的思維解決 面向對象:問題較為複雜,使用簡單的線性思維無法解決 兩種編程思想都是解決問題的方式,並不對立,通過面向對象的方式便於我們從巨集觀上把握事物之間的複雜關係、便於我們分析整個系統。本質仍然使用面向過程的方式來處理。 面向對象的程式設計強調把數據和操 ...


編程思想:

  • 面向過程:問題比較簡單,可以用線性的思維解決
  • 面向對象:問題較為複雜,使用簡單的線性思維無法解決

  兩種編程思想都是解決問題的方式,並不對立,通過面向對象的方式便於我們從巨集觀上把握事物之間的複雜關係、便於我們分析整個系統。本質仍然使用面向過程的方式來處理

  面向對象的程式設計強調把數據和操作結合為一個不可分割的系統單位(即對象),對象的外部只需要知道它在做什麼,而不需要知道怎麼做。

類和對象:

類是抽象的模板,而實例是根據類創建出來的一個個具體的 ”對象“ ,每個對象都擁有相同的方法,但各自的數據可能不相同。

類:

  類是多個類似事物組成的群體的總稱。能夠幫助我們快速理解和判斷事物的性質。

1 class 類名( object ): # 類名有一個或多個單詞構成,每個單詞首字母大寫其餘小寫,用下劃線連接
2     pass

 

  Tip : object 表示該類是從哪個類繼承(後補充)下來的,通常,如果沒有合適的繼承類,就使用 object 類,這是所有類都會繼承的類。

數據類型:

  • 不同的數據類型屬於不同的類。
  • 可以使用  type()  函數來查看變數的數據類型。

對象:

   對象是類的具體實例(instance),python 中一切皆對象

   類是一種數據結構,類定義數據類型的數據(屬性 )和行為(方法)。對象是類的具體實體,也可以稱為類的實例。需要註意,類的實例和實例對象有時不那麼容易區分但又不是同一個東西。在在用class 關鍵字創建自定義的類對象的時,創建的是類的實例;而後者是用類對象創建實例對象。

  Python中一切皆對象;類定義完成後,會在當前作用域中定義一個以類名為名字,指向類對象的變數(名字)。

屬性:

Generally speaking, instance variables are for data unique to each instance and class variables are for attributes and methods shared by all instances of the class:

 

類數據屬性:

  類屬性是某個類所有實例共用的屬性,在創建實例對象時,每個實例都會擁有類數據屬性的一個拷貝。

實例變數屬性:

  由類中__ init __() 方法定義的屬性(變數)。通過 “ . ”來訪問。在每個實例對象初始化時都會賦予獨有的數據。 

舉幾個慄子:

1 class Student:
2     
3     school = JXNU             # class variable shared by all instances
4     
5     def __init__(self, name):
6         self.name = name      # instance variable unique to each instance
 1 class Student:
 2     school = 'JXNU'
 3 
 4     def __init__(self, name):
 5         self.name = name
 6 
 7 
 8 stu1 = Student('Zhang')
 9 stu2 = Student('Li')
10 
11 print(stu1.school)    # =>JXNU
12 print(stu2.school)    # =>JXNU
13 
14 print('-'*20)
15 Student.school = 'SDJU'
16 print(stu1.school)    # =>SDNU
17 print(stu2.school)    # =>SDNU
18 
19 print('-'*20)
20 stu1.school = 'ZJNU'
21 print(stu2.school)    # =>SDNU
22 print(stu1.school)    # =>ZJNU
23 
24 print('-'*20)
25 Student.school = 'PJNU'
26 print(stu1.school)    # =>ZJNU
27 print(stu2.school)    # =>PJNU
  • 所有的實例初始化時都創建了一個指向同一個類屬性的指針。用類名Student修改類屬性school時,實例中的school也會發生改變。而用實例 stu1 修改對應的 school 時,指針將不指向原來的類屬性了,而是指向其他的變數。
  • 類 Student 中,類屬性 school 為所有實例共用;實例屬性 name 為每個 Student 的實例獨有。
  • 實例屬性是不能用類名訪問的屬性,必須由實例名 + ‘ . ' 來訪問。且每個實例對應一套。

私有屬性和公有屬性:

通常約定以兩個下劃線開頭而不以兩個下劃線結尾的變數為私有變數,其他的為公有變數。不能直接訪問私有變數,但可以在方法中訪問。

特殊屬性:

類屬性

含義

__name__

類的名字(字元串)

__doc__

類的文檔字元串

__bases__

類的所有父類組成的元組

__dict__

類的屬性組成的字典

__module__

類所屬的模塊

__class__

類對象的類型

方法:

實例方法:

一般需要傳遞 self 參數用於調用實例的實例屬性(變數),且只能由實例訪問。沒有矛盾和衝突點不做贅述。

類方法:

  • 用 @classmethod 修飾的方法,可以用類名直接訪問。第一個參數必須是當前類對象,該參數名一般約定為“cls”,通過它來傳遞類的屬性和方法(不能傳實例的屬性和方法)。
  • 原則上,類方法是將類本身作為對象進行操作的方法。假設有個方法,這個方法在邏輯上採用類本身作為對象來調用更合理,那麼這個方法就可以定義為類方法。另外,如果需要繼承,也可以定義為類方法。

 

靜態方法:

  • 用 @staticmethod 修飾的方法,可以用類名直接訪問。第一個參數必須是當前類對象,該參數名一般約定為“cls”,通過它來傳遞類的屬性和方法(不能傳實例的屬性和方法)。
  • 靜態方法是類中的函數,不需要實例。靜態方法主要是用來存放邏輯性的代碼,邏輯上屬於類,但是和類本身沒有關係,也就是說在靜態方法中,不會涉及到類中的屬性和方法的操作。可以理解為,靜態方法是個獨立的、單純的函數,它僅僅托管於某個類的名稱空間中,便於使用和維護。
  • 靜態方法更像是可以寫在類外的函數,但這樣是為了在邏輯上與類保持一定聯繫,不破壞類的邏輯性。

  類方法和靜態方法的用途有時會混淆。

舉幾個慄子:

  * 類方法慄子

 1 情景:
 2 假設我有一個學生類和一個班級類,想要實現的功能為:
 3     執行班級人數增加的操作、獲得班級的總人數;
 4     學生類繼承自班級類,每實例化一個學生,班級人數都能增加;
 5     最後,我想定義一些學生,獲得班級中的總人數。
 6 
 7 class ClassTest(object):
 8     __num = 0
 9 
10     @classmethod
11     def addNum(cls):
12         cls.__num += 1
13 
14     @classmethod
15     def getNum(cls):
16         return cls.__num
17 
18     # 這裡我用到魔術方法__new__,主要是為了在創建實例的時候調用累加方法。
19     def __new__(self):
20         ClassTest.addNum()
21         return super(ClassTest, self).__new__(self)
22 
23 
24 class Student(ClassTest):
25     def __init__(self):
26         self.name = ''
27 
28 a = Student()
29 b = Student()
30 print(ClassTest.getNum())

  * 靜態方法慄子

 1 import time
 2 
 3 class TimeTest(object):
 4     def __init__(self, hour, minute, second):
 5         self.hour = hour
 6         self.minute = minute
 7         self.second = second
 8 
 9     @staticmethod
10     def showTime():
11         return time.strftime("%H:%M:%S", time.localtime())
12 
13 
14 print(TimeTest.showTime())
15 t = TimeTest(2, 10, 10)
16 nowTime = t.showTime()
17 print(nowTime)

 

實例屬性和方法的動態綁定:

話不多說,直接上代碼:

 1 class Student:
 2     def __init__(self, name):
 3         self.name = name
 4 
 5 
 6 stu1 = Student('Zhang')
 7 stu2 = Student('Li')
 8 
 9 stu1.age = 20
10 print(stu1.age)    # =>20
11 print(stu2.age)    # AttributeError: 'Student' object has no attribute 'age'
12 
13 ### 追加的屬性或者方法只屬於這一實例不能用於共用。 ###

 

面向對象的三大特征:

封裝:

  • 將數據(屬性)和方法打包到類對象中。在方法內部對屬性進行操作,在類對象的外部調用方法。這樣就無需關心方法內部的複雜實現,從而將實現和使用相分離。由類和對象來實現。
  • 調用封裝內容可以直接用類名也可以創建一個類的實例。

繼承:

  • 提高代碼的復用性。
  • 將多個類共有的方法提取到父類中,子類僅需繼承父類而不必一一實現每個
     1 class 父類(object):
     2     def 父類中的方法(self):
     3         # doing sth
     4 
     5 
     6 class 子類(父類):   # 子類繼承父類,即繼承了父類中的所有方法
     7     pass
     8 
     9 
    10 zi = 子類()         # 創建子類的實例對象
    11 
    12 zi.父類中的方法()    # 執行從父類中繼承的方法

     

  • 不同於Java、C++,Python允許多繼承。類繼承了多個類時尋找方法的方式有兩種,分別是深度優先廣度優先。經典類多繼承是會按深度優先搜索方法;新式類則是按廣度優先搜索。這樣區分經典類和新式類呢?從字面上可以看出一個老一個新,新的必然包含了跟多的功能,也是之後推薦的寫法,從寫法上區分的話,如果當前類或者父類繼承了object類,那麼該類便是新式類,否則便是經典類。搜索有先後順序,所以不會產生多個同名方法的衝突。

多態:

  •  Pyhon不支持Java和C#這一類強類型語言中多態的寫法,但是原生多態,Python 本身就是一種多態語言。Python崇尚“鴨子類型”(duck typing)。

在程式設計中,鴨子類型(英語:duck typing)是動態類型的一種風格。在這種風格中,一個對象有效的語義,不是由繼承自特定的類或實現特定的介面,而是由當前方法和屬性的集合決定。這個概念的名字來源於由James Whitcomb Riley提出的鴨子測試,“鴨子測試”可以這樣表述:

    “當看到一隻鳥走起來像鴨子、游泳起來像鴨子、叫起來也像鴨子,那麼這隻鳥就可以被稱為鴨子。”

在鴨子類型中,關註的不是對象的類型本身,而是它是如何使用的。例如,在不使用鴨子類型的語言中,我們可以編寫一個函數,它接受一個類型為鴨的對象,並調用它的走和叫方法。在使用鴨子類型的語言中,這樣的一個函數可以接受一個任意類型的對象,並調用它的走和叫方法。如果這些需要被調用的方法不存在,那麼將引發一個運行時錯誤。任何擁有這樣的正確的走和叫方法的對象都可被函數接受的這種行為引出了以上表述,這種決定類型的方式因此得名。

鴨子類型通常得益於不測試方法和函數中參數的類型,而是依賴文檔、清晰的代碼和測試來確保正確使用。從靜態類型語言轉向動態類型語言的用戶通常試圖添加一些靜態的(在運行之前的)類型檢查,從而影響了鴨子類型的益處和可伸縮性,並約束了語言的動態特性。

 1 class F1:
 2     pass
 3 
 4 
 5 class S1(F1):
 6 
 7     def show(self):
 8         print 'S1.show'
 9 
10 
11 class S2(F1):
12 
13     def show(self):
14         print 'S2.show'
15 
16 def Func(obj):
17     print obj.show()
18 
19 s1_obj = S1()
20 Func(s1_obj) 
21 
22 s2_obj = S2()
23 Func(s2_obj) 
24 
25 ### Python “鴨子類型” ###

 

小結:

  • 面向對象是一種編程方式,此編程方式的實現是基於對  和 對象 的使用
  • 類 是一個模板,模板中包裝了多個“函數”供使用
  • 對象,根據模板創建的實例(即:對象),實例用於調用被包裝在類中的函數
  • 面向對象三大特性:封裝、繼承和多態

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

-Advertisement-
Play Games
更多相關文章
  • 寫在前面 本系列的文章是博主邊學邊記錄的,可能不是特別的正確,因為會加上博主自己的理解,僅供參考。 正文: 為了能夠將用戶程式裝入記憶體,必須為它分配一定大小的記憶體空間。常見的分配方式有: 1.連續分配 連續分配方式是最早出現的一種存儲器分配方式,該分配方式為一個用戶程式分配一個連續的記憶體空間。常見的 ...
  • 文本編輯工具VIM 1.vi/vim介紹 我們要學會如何去新建文件、刪除文件、修改文件等等,那麼做這些操作就需要一個文本編輯工具。而在linux中最經典最流行的文本編輯工具就是vi/vim,當然也有一些其他的文本編輯工具。 例如 emacs pico nano joe jed 諸如此類,但我們只需要 ...
  • SiteSucker for Mac是一款運行在Mac平臺上的整站下載工具,在SiteSucker Mac版中輸入網址就能離線下載一個網站里的所有內容,包括HTML、圖片、CSS 樣式表、JS 文件、Flash 文件等,SiteSucker for mac版的操作十分簡單,非常的實用。 詳情:Sit ...
  • 1.軟體下載 [root@localhost ~]# cd /usr/src/ [root@localhost src]# wget https://downloads.mysql.com/archives/get/p/23/file/mysql-5.7.38-linux-glibc2.12-x86 ...
  • 20 | 幻讀是什麼,幻讀有什麼問題? 建表和初始化語句如下 CREATE TABLE `t` ( `id` int(11) NOT NULL, `c` int(11) DEFAULT NULL, `d` int(11) DEFAULT NULL, PRIMARY KEY (`id`), KEY ` ...
  • 業務端需要求連續90日每日的用戶留存率改怎麼計算呢??? 一: 本文采用MySQL8.0環境 1: 建表數據 CREATE TABLE `user_login` ( `user_id` int NOT NULL, `login_date` varchar(20) CHARACTER SET utf8 ...
  • 我們已經介紹瞭如何在 Kubernetes 和 KubeSphere 上部署 RadonDB MySQL 集群。本文將演示如何在 Rancher[1] 上部署 RadonDB MySQL Kubernetes 2.2.0[2],快速獲得一套 MySQL 容器化集群。 部署準備 已部署 Rancher ...
  • --創建用戶① --GRANT(授權)REVOKE(回收許可權)--創建用戶create user 用戶名 identified by 密碼 GRANT CONNECT,RESOURCE TO 用戶;GRANT CREATE VIEW TO 用戶;GRANT CREATE SYNONYM TO 用戶; ...
一周排行
    -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.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...