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.軟體下載 [[email protected] ~]# cd /usr/src/ [[email protected] 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
  • 使用原因: 在我們服務端調用第三方介面時,如:支付寶,微信支付,我們服務端需要模擬http請求並加上一些自己的邏輯響應給前端最終達到我們想要的效果 1.使用WebClient 引用命名空間 using System.Net; using System.Collections.Specialized; ...
  • WPF 實現帶蒙版的 MessageBox 消息提示框 WPF 實現帶蒙版的 MessageBox 消息提示框 作者:WPFDevelopersOrg 原文鏈接: https://github.com/WPFDevelopersOrg/WPFDevelopers.Minimal 框架使用大於等於.N ...
  • 一、JSON(JavaScript Object Notation)的簡介: ① JSON和XML類似,主要用於存儲和傳輸文本信息,但是和XML相比,JSON更小、更快、更易解析、更易編寫與閱讀。 ② C、Python、C++、Java、PHP、Go等編程語言都支持JSON。 二、JSON語法規則: ...
  • 1.避免Scoped模式註冊的服務變成Singleton模式 當提供一個生命周期模式為Singleton的服務實例時,如果發現該服務中還依賴生命周期模式為Scoped的服務實例(Scoped服務實例將被一個Singleton服務實例所引用),那麼這個被依賴的Scoped服務實例最終會成為一個Sing ...
  • 索引時資料庫提高數據查詢處理性能的一個非常關鍵的技術,索引的使用可以對性能產生上百倍甚至上千倍的影響。接下來,會介紹索引的基本原理、概念,並深入學習資料庫中所使用的索引結構和存儲方式,以及如何管理、維護索引等。 1.索引的基本概念 索引時用來快速查詢表記錄的一種存儲結構,一般使用索引有一下兩個方面: ...
  • django2 路由控制器 Route路由,是一種映射關係。路由是把客戶端請求的url路徑和用戶請求的應用程式,這裡意指django裡面的視圖進行綁定映射的一種關係。 請求路徑和視圖函數不是一一對應的關係 在django中所有的路由最終都被保存到一個叫urlpatterns的文件里,並且該文件必須在 ...
  • 1、我們的目標是獲取微博某博主的全部圖片、視頻 2、拿到網址後 我們先觀察 打開F12 隨著下滑我們發現載入出來了一個叫mymblog的東西,展開響應發現需要的東西就在裡面 3、重點來了!!! 通過觀察發現第二頁比第一頁多了參數since_id 而第二頁的since_id參數剛好在上一頁中能獲取到, ...
  • 一、實現原理 在Servlet3協議規範中,包含在JAR文件/META-INFO/resources/路徑下的資源可以直接訪問。 二、舉例說明 如下圖所示,是我新建的一個Spring Boot Starter項目:zimug-minitor-threadpool,用於實現可配置、可觀測的線程池。其中 ...
  • 精華筆記: static final常量:應用率高 必須聲明同時初始化 由類名打點來訪問,不能被改變 建議:常量所有字母都大寫,多個單詞用_分隔 編譯器在編譯時會將常量直接替換為具體的數,效率高 何時用:數據永遠不變,並且經常使用 抽象方法: 由abstract修飾 只有方法的定義,沒有具體的實現( ...
  • Python有一個for...else語法,它的寫法如下 for i in range(0,100): if i == 3: break else: print("Not found") 該語句表示:若for迴圈遍歷完畢,則執行else部分的語句。也就是說上述代碼不會有任何輸出,而下述代碼會輸出“N ...