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
  • Timer是什麼 Timer 是一種用於創建定期粒度行為的機制。 與標準的 .NET System.Threading.Timer 類相似,Orleans 的 Timer 允許在一段時間後執行特定的操作,或者在特定的時間間隔內重覆執行操作。 它在分散式系統中具有重要作用,特別是在處理需要周期性執行的 ...
  • 前言 相信很多做WPF開發的小伙伴都遇到過表格類的需求,雖然現有的Grid控制項也能實現,但是使用起來的體驗感並不好,比如要實現一個Excel中的表格效果,估計你能想到的第一個方法就是套Border控制項,用這種方法你需要控制每個Border的邊框,並且在一堆Bordr中找到Grid.Row,Grid. ...
  • .NET C#程式啟動閃退,目錄導致的問題 這是第2次踩這個坑了,很小的編程細節,容易忽略,所以寫個博客,分享給大家。 1.第一次坑:是windows 系統把程式運行成服務,找不到配置文件,原因是以服務運行它的工作目錄是在C:\Windows\System32 2.本次坑:WPF桌面程式通過註冊表設 ...
  • 在分散式系統中,數據的持久化是至關重要的一環。 Orleans 7 引入了強大的持久化功能,使得在分散式環境下管理數據變得更加輕鬆和可靠。 本文將介紹什麼是 Orleans 7 的持久化,如何設置它以及相應的代碼示例。 什麼是 Orleans 7 的持久化? Orleans 7 的持久化是指將 Or ...
  • 前言 .NET Feature Management 是一個用於管理應用程式功能的庫,它可以幫助開發人員在應用程式中輕鬆地添加、移除和管理功能。使用 Feature Management,開發人員可以根據不同用戶、環境或其他條件來動態地控制應用程式中的功能。這使得開發人員可以更靈活地管理應用程式的功 ...
  • 在 WPF 應用程式中,拖放操作是實現用戶交互的重要組成部分。通過拖放操作,用戶可以輕鬆地將數據從一個位置移動到另一個位置,或者將控制項從一個容器移動到另一個容器。然而,WPF 中預設的拖放操作可能並不是那麼好用。為瞭解決這個問題,我們可以自定義一個 Panel 來實現更簡單的拖拽操作。 自定義 Pa ...
  • 在實際使用中,由於涉及到不同編程語言之間互相調用,導致C++ 中的OpenCV與C#中的OpenCvSharp 圖像數據在不同編程語言之間難以有效傳遞。在本文中我們將結合OpenCvSharp源碼實現原理,探究兩種數據之間的通信方式。 ...
  • 一、前言 這是一篇搭建許可權管理系統的系列文章。 隨著網路的發展,信息安全對應任何企業來說都越發的重要,而本系列文章將和大家一起一步一步搭建一個全新的許可權管理系統。 說明:由於搭建一個全新的項目過於繁瑣,所有作者將挑選核心代碼和核心思路進行分享。 二、技術選擇 三、開始設計 1、自主搭建vue前端和. ...
  • Csharper中的表達式樹 這節課來瞭解一下表示式樹是什麼? 在C#中,表達式樹是一種數據結構,它可以表示一些代碼塊,如Lambda表達式或查詢表達式。表達式樹使你能夠查看和操作數據,就像你可以查看和操作代碼一樣。它們通常用於創建動態查詢和解析表達式。 一、認識表達式樹 為什麼要這樣說?它和委托有 ...
  • 在使用Django等框架來操作MySQL時,實際上底層還是通過Python來操作的,首先需要安裝一個驅動程式,在Python3中,驅動程式有多種選擇,比如有pymysql以及mysqlclient等。使用pip命令安裝mysqlclient失敗應如何解決? 安裝的python版本說明 機器同時安裝了 ...