Python知識點13---面向對象的編程

提前說一點:如果你是專注于Python開發,那么本系列知識點只是帶你入個門再詳細的開發點就要去看其他資料了,而如果你和作者一樣只是操作其他技術的Python API那就足夠了。

Python是一個完全面向對象開發的語言,它的一切都以對象的方式操作

類(Class): 用來描述具有相同的屬性和方法的對象的集合。它定義了該集合中每個對象所共有的屬性和方法。對象是類的實例。
類變量:類變量在整個實例化的對象中是公用的。類變量定義在類中且在函數體之外。類變量通常不作為實例變量使用。
數據成員:類變量或者實例變量, 用于處理類及其實例對象的相關的數據。
方法重寫:如果從父類繼承的方法不能滿足子類的需求,可以對其進行改寫,這個過程叫方法的覆蓋(override),也稱為方法的重寫。
局部變量:定義在方法中的變量,只作用于當前實例的類。
實例變量:在類的聲明中,屬性是用變量來表示的。這種變量就稱為實例變量,是在類聲明的內部但是在類的其他成員方法之外聲明的。
繼承:即一個派生類(derived class)繼承基類(base class)的字段和方法。繼承也允許把一個派生類的對象作為一個基類對象對待。例如,有這樣一個設計:一個Dog類型的對象派生自Animal類,這是模擬"是一個(is-a)"關系(例圖,Dog是一個Animal)。
實例化:創建一個類的實例,類的具體對象。
方法:類中定義的函數。
對象:通過類定義的數據結構實例。對象包括兩個數據成員(類變量和實例變量)和方法。

定義一個類的語法如下,注意如果你用的是Python2,那么不要寫objeck,不然會報錯的

class ClassName(objeck):'類的幫助信息'   #類文檔字符串class_suite  #類體#類的實例方法def aaa(self) :return

實例化類,生成對象語法如下

變量名 = 類名()  ---不需要其他語言那樣的new

Python的類里面,和其他語言不同的就是,有時方法中會多一個 self,這個變量你要使用的時候,一般都是放在第一個參數位,并且代表對象本身,下面這個例子可以解釋這一點

class Test:def prt(self):print(self)t = Test()
print(t)
t.prt()結果發現指向的都是同一個對象:
<__main__.Test instance at 0x10d066878>
<__main__.Test instance at 0x10d066878>

切記:對于 self 本身來說,它不是一個定死的關鍵字,我們換成其他的名字也可以,只是在開發中我們按照慣例,把它寫在了第一個參數位,并且起名為 self ,它本身其實是和JAVA的this對象等價的,只不過Python需要在參數位聲明一下而已

而且當你使用了self的時候,在傳遞參數時,不需要在意它的值,因為可以自動補齊,如下

class Test :def fun_name(self,b,c):print(b+str(c))a = Test()
a.fun_name('忽略self正常傳參',21)
結果:忽略self正常傳參21

對于Python的類來說,也是擁有屬性的,我們在類的內部,類實體方法的外部,書寫屬性即可,但是切記在類中書寫屬性的時候一定要給一個初值,不然訪問的時候會報錯

class Test :age = ''def fun_test():print('llll')

在使用這個類創建對象之后,對象會擁有類的所有東西,屬性自然也包括其中,調用時語法如下,這一點在Python中叫做 “類外面獲取對象屬性

對象名.屬性名		#調用獲取
對象名.屬性名 =#修改

但是注意,Python允許一個對象擁有屬于自己的屬性,這種屬性不需要在類中定義,直接使用對象調用就可以,會自動生成一個數據這個對象自己的屬性,其他對象沒有,下面這個例子可以解釋這一點,這一點在Python中也叫做 “類外面添加對象屬性

class Test :def fun_name():print('llll')a = Test()
b = Test()a.age = '12'
print(a.age)
print(b.age)結果會報錯,提示對象b沒有age屬性:
12
Traceback (most recent call last):File "main.py", line 12, in <module>print(b.age)
AttributeError: Test instance has no attribute 'age'

這個時候有的小伙伴可能就會疑惑,有類外面獲取對象屬性、類外面添加對象屬性,這兩點都聚焦在對象的身上,和類的關系不是很明顯,其實Python還有最后一種相關操作,叫做“在類內部獲取對象屬性”,對于這一點,個人認為其實是Python提供給我們開發者的一種輔助,防止我們由于其他因素導致訪問不到對象的屬性,比如被局部變量或者其他變量干擾,操作方式如下

class Test :age = 12def fun_name(self):print(self.age)a = Test()
a.fun_name()

其實就是self的應用,不過注意,這種操作可以和類外部添加屬性那樣直接調用一個原先沒有的屬性

class Test :def fun_name(self):print(self.age)a = Test()
a.age = 10
a.fun_name()

現在我猜測大家或許會混亂,沒關系,記住核心的一點:在Python中,可以像常規那樣使用對象和類,只是Python除此之外,允許一個屬性在使用的時候,是從無到有的,也就是沒有被預先定義的

其實對于self來說,它不止可以調用我們自己定義的屬性,它還帶有著其他的東西,有興趣大家可以在其他地方找一找資料,比如可以獲取對象實例化的類名

class Test :def fun_name(self):print(self.__class__)a = Test()
a.fun_name()結果:__main__.Test

對于對象的屬性,Python其實有著其他的方式可以調用

getattr(obj, name[, default]) : 訪問對象的屬性。
hasattr(obj,name) : 檢查是否存在一個屬性。
setattr(obj,name,value) : 設置一個屬性。如果屬性不存在,會創建一個新屬性。
delattr(obj, name) : 刪除屬性。hasattr(emp1, 'age')    # 如果存在 'age' 屬性返回 True。
getattr(emp1, 'age')    # 返回 'age' 屬性的值
setattr(emp1, 'age', 8) # 添加屬性 'age' 值為 8
delattr(emp1, 'age')    # 刪除屬性 'age'

Python類的本身其實也有自帶的被規定的屬性,俗稱類屬性,為什么說它被規定呢?這個后面我會解釋

調用的時候用   類名.類屬性    就可以了__dict__ : 類的屬性(包含一個字典,由類的數據屬性組成)
__doc__ :類的文檔字符串
__name__: 類名
__module__: 類定義所在的模塊
__bases__ : 類的所有父類構成元素(包含了一個由所有父類組成的元組)

有意思的是我們通過類名可以直接將自己定義的屬性獲取到,這個時候,這個屬性也叫做類屬性


下面我們了解一下,在Python中對象是如何被垃圾回收的

在Python中只有一種垃圾回收機制,就是引用計數法,在 Python 內部記錄著所有使用中的對象各有多少引用。

一個內部跟蹤變量,稱為一個引用計數器。

當對象被創建時, 就創建了一個引用計數, 當這個對象不再需要時, 也就是說, 這個對象的引用計數變為0 時, 它被垃圾回收。但是回收不是"立即"的, 由解釋器在適當的時機,將垃圾對象占用的內存空間回收。

垃圾回收機制不僅針對引用計數為0的對象,同樣也可以處理循環引用的情況。循環引用指的是,兩個對象相互引用,但是沒有其他變量引用他們。這種情況下,僅使用引用計數是不夠的。Python 的垃圾收集器實際上是一個引用計數器和一個循環垃圾收集器。作為引用計數的補充, 垃圾收集器也會留心被分配的總量很大(即未通過引用計數銷毀的那些)的對象。 在這種情況下, 解釋器會暫停下來, 試圖清理所有未引用的循環,其實說白了就是有a、b兩個對象,它們獨立與其他對象,產生較為單獨的一對相互引用關系,這種對象時間長了,也會被回收掉

特別注意一個對象被回收時,會調用它的__del__方法,這個方法是用來回收對象的,但大家不要糾結,后面我會單獨說這種有四個下滑線的方法,是干什么的


下面我們來了解一下類的繼承,類繼承語法如下

class 派生類名(基類名):...

Python的類繼承的時候,和其他語言一樣有著注意點:

1、如果在子類中需要父類的構造方法就需要顯式的調用父類的構造方法,或者不重寫父類的構造方法。實例如下

當你沒有重寫構造方法時:
class Father():def __init__(self, name):self.name=namedef getName(self):return 'Father ' + self.nameclass Son(Father):def getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )結果:Son runoob
從結果中你可以發現,傳入的name值作用在了父類的構造器上-----------------------------------------------------------------------------
當你重寫了子類的構造方法,但是沒有調用父類的時候:
class Father():def __init__(self, name):self.name=namedef getName(self):return 'Father ' + self.nameclass Son(Father):def __init__(self, name):print ( "hi" )self.name =  namedef getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )結果:
hi
Son runoob
從結果來看,發現并沒有調用父類的構造方法------------------------------------------------------------
當你重寫了子類的構造方法,并調用了父類的構造方法時:
class Father():def __init__(self, name):self.name = nameprint("這里是父類")class Son(Father):def __init__(self, name):#第一種調用方法:super(Son, self).__init__(name)#第二種調用方法:Father.__init__(self,name)print ("hi")self.name =  namedef getName(self):return 'Son '+self.nameson=Son('runoob')
print ( son.getName() )
結果:
這里是父類
hi
Son runoob

2、在調用基類的方法時,基類的方法必須有self參數,不然無法執行,對于這一點其實大家養成寫方法參數要帶上self的習慣就可以了

基類沒有self:
class Father():def __init__(self, name):self.name = namedef nnn():print('父類方法')class Son(Father):def __init__(self, name):Father.__init__(self,name)self.name =  nameson=Son('runoob')
son.nnn()
結果報錯:
Traceback (most recent call last):File "main.py", line 17, in <module>son.nnn()
TypeError: nnn() takes no arguments (1 given)----------------------------------------------------------------
基類有self
class Father():def __init__(self, name):self.name = namedef nnn(self):print('父類方法')class Son(Father):def __init__(self, name):Father.__init__(self,name)self.name =  nameson=Son('runoob')
son.nnn()
結果:父類方法

3、Python 總是首先查找對應類型的方法,如果它不能在派生類中找到對應的方法,它才開始到基類中逐個查找。(先在本類中查找調用的方法,找不到才去基類中找)。


值得高興的是Python支撐多繼承

class A:        # 定義類 A
.....class B:         # 定義類 B
.....class C(A, B):   # 繼承類 A 和 B
.....

還提供了兩個檢查函數

issubclass()  布爾函數判斷一個類是另一個類的子類或者子孫類,語法:issubclass(子類,父類)
isinstance(obj, Class) 布爾函數如果obj是Class類的實例對象或者是一個Class子類的實例對象則返回true

Python也支持多態,在重寫父類方法的時候也要注意self

class Father():def __init__(self, name):self.name = namedef nnn(self):print('父類方法')class Son(Father) :def __init__(self, name) :Father.__init__(self,name)self.name = namedef nnn(self,age) :print('子類方法' + str(age))def nnn(self,age,ppp) :print('子類方法' + str(age) + str(ppp))a = Son('Tom')
a.nnn(10)
a.nnn(10,20)
結果:
子類方法10
子類方法1020

如果看了我寫的公共方法篇,一定知道加法是合并的意思,而有趣的是Python的對象也支持這樣的操作,不過想要對象之間執行合并你需要重寫__add__方法

class Vector:def __init__(self, a, b):self.a = aself.b = bdef __str__(self):return 'Vector (%d, %d)' % (self.a, self.b)def __add__(self,other):return Vector(self.a + other.a, self.b + other.b)v1 = Vector(2,10)
v2 = Vector(5,-2)
print v1 + v2
結果:Vector (7, 8)

值得一提的是,在Python中類也是有靜態方法的
class Father():def __init__(self, name):self.name = name@staticmethoddef nnn(self):print('靜態方法')Father.nnn()
a = Father('Tom')
a.nnn()

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/bicheng/20308.shtml
繁體地址,請注明出處:http://hk.pswp.cn/bicheng/20308.shtml
英文地址,請注明出處:http://en.pswp.cn/bicheng/20308.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

Java面試——專業技能

優質博文&#xff1a;IT-BLOG-CN 一、簡單講下 Java 的跨平臺原理 由于各個操作系統&#xff08;Windows&#xff0c;Linux等&#xff09;支持的指令集不是完全一致的。就會讓我們程序在不同的操作系統上要執行不同的程序代碼。Java 開發了適用于不同操作系統及位數的 Java 虛擬…

【教程】自監督 對比學習,代碼,爽學一波

from&#xff1a; https://docs.lightly.ai/self-supervised-learning/examples/simclr.html

代碼隨想錄第22天|回溯part2 組合總和III電話號碼的字母組合

216.組合總和III 當組合的數量為k就判斷和&#xff0c;并且返回。 在枚舉的時候可以進行剪枝&#xff0c;如果總和已經超過了n&#xff0c;那么就沒必要繼續遞歸下去了 class Solution { public:vector<int> path;vector<vector<int>> res;void backTrackin…

微信小程序手機號碼授權登錄

文章目錄 一、微信小程序開發二、使用步驟1.前端代碼2.后臺配置3.后臺代碼 總結 一、微信小程序開發 目前個人的小程序無法使用手機號碼授權登錄&#xff0c;可以使用測試號進行開發 二、使用步驟 1.前端代碼 代碼如下&#xff08;示例&#xff09;&#xff1a; <butto…

Java版本家政上門系統源碼,自主研發、安全可控,支持任意二次開發

家政上門系統源碼&#xff0c;Java版本&#xff0c;自主研發、安全可控。支持任意二次開發、有豐富合作案例。多端管理&#xff1a;管理端、用戶端、服務端。 技術參數&#xff1a; 技術架構&#xff1a;springboot、mysql 、Thymeleaf 開發語言&#xff1a;java1.8、vue 開…

python 象棋小游戲代碼

以下是一個簡單的Python象棋小游戲的代碼示例。這個示例使用了pygame庫來創建圖形用戶界面和處理用戶輸入。 首先&#xff0c;確保安裝了pygame庫&#xff1a; pip install pygame 然后&#xff0c;可以運行以下代碼&#xff1a; import pygame import sys # 初始化pygam…

軟件開發步驟詳解

一、引言 隨著信息技術的迅猛發展&#xff0c;軟件已成為現代社會不可或缺的一部分。無論是企業運營、個人生活還是科學研究&#xff0c;都離不開各種軟件的支持。因此&#xff0c;掌握軟件開發的步驟和技巧對于IT從業者來說至關重要。本文旨在詳細介紹軟件開發的整個流程&…

Python知識點7---字典與集合

提前說一點&#xff1a;如果你是專注于Python開發&#xff0c;那么本系列知識點只是帶你入個門再詳細的開發點就要去看其他資料了&#xff0c;而如果你和作者一樣只是操作其他技術的Python API那就足夠了。 Python的字典與集合是沒有下標一說的&#xff0c;字典說的其實就是ma…

使用機器學習做醫學圖像分類的開源項目集錦

項目名稱倉庫描述主要特點適配建議U-Net用于生物醫學圖像分割zhixuhao/unetKeras中的U-Net實現&#xff0c;用于2D圖像分割。 - 基本的U-Net架構 - 生物醫學圖像訓練示例 - 簡單的數據加載器 - 修改數據加載器以處理特定MRI格式 - 調整訓練管道以適應STIR序列和標簽 使用PyTor…

更改Web網站設計——css和css框架

雖然使用HTML可以定義文章的結構&#xff0c;但是其中不包含設計相關的信息。此時CSS就派上用場&#xff0c;可以用它對HTML文章指定設計樣式。由于可以決定Web網頁的外觀風格&#xff0c;因此&#xff0c;它有時也被稱為格式表。 如果使用CSS設置背景色&#xff0c;文…

計算機網絡期末復習(1)計算機網絡在信息時代對的作用 計算機網絡的定義和分類 三種交換方法

計算機網絡在信息時代扮演著至關重要的角色&#xff0c;它極大地改變了我們生活、工作和學習的方式。 計算機網絡在信息時代的作用 信息共享與傳播&#xff1a;計算機網絡使全球范圍內的信息快速共享成為可能&#xff0c;無論是新聞、學術研究還是娛樂內容&#xff0c;都可以…

初識 JavaScript

目錄 1. 什么是 JavaScript2. JS 引入方式2.1 內部引入方式2.2 外部引入方式 3. JS 中的注釋4. JS 中的結束符5. 輸入和輸出5.1 輸出5.2 輸入 6. 變量與常量6.1 變量的聲明6.2 變量的賦值6.3 常量 7. JS 中的數據類型8. JS 中的類型轉換8.1 隱式轉換8.2 顯式轉換 正文開始 1. …

Java 多線程相關面試題

1. ConcurrentHashMap的讀是否要加鎖&#xff0c;為什么? 讀操作沒有加鎖&#xff0c;目的是為了進一步降低鎖沖突的概率&#xff0c;為了保證讀到剛修改的數據&#xff0c;搭配了volatile 關鍵字&#xff1b; 2. 介紹下 ConcurrentHashMap 的鎖分段技術? 這個是 Java1.7 …

TP8 定時任務yzh52521/http-crontab 教程

官方文檔&#xff1a; https://www.thinkphp.cn/ext/36 源碼倉&#xff1a; http-crontab: 接口化秒級定時任務管理 GitHub - yuanzhihai/http-crontab: 接口化秒級定時任務管理 參考案例&#xff1a; http-crontab:Workerman ThinkPHP6 實現后臺可視化定時任務管理 htt…

深入解析Java注解機制:元注解、自定義處理器及其在框架中的妙用

1.注解簡介與作用 1.1 什么是注解&#xff08;Annotation&#xff09; 在Java中&#xff0c;注解是一種應用于類、方法、變量、參數和Java包等元素的標記。這些標記可以在編譯時、加載時甚至運行時被讀取&#xff0c;并執行相應的處理。通過使用注解&#xff0c;開發人員可以…

C++中的List

摘要 C 標準庫中的 std::list 是一種雙向鏈表容器&#xff0c;它允許在常數時間內進行插入和刪除操作&#xff0c;每個元素包含一個指向前一個和后一個元素的指針。這給我們開發提供了高效的插入和刪除操作。 引入頭文件 要使用 std::list&#xff0c;需要包含頭文件 <li…

鈑金件設計規范

(一&#xff09; 鈑金 1、鈑金的概念 鈑金&#xff08;sheet metal&#xff09;是針對金屬薄板&#xff08;厚度通常在6mm以下&#xff09;的 一種綜合冷加工工藝&#xff0c;包括沖裁、折彎、拉深、成形、鍛壓、鉚合等&#xff0c; 其顯著的特征是同一零件厚度一致。 2、鈑…

C語言屬于什么是編程語言:探索C語言的本質與特性

C語言屬于什么是編程語言&#xff1a;探索C語言的本質與特性 在編程領域&#xff0c;C語言無疑是一種重要的、廣泛應用的編程語言。但是&#xff0c;C語言究竟屬于哪一類編程語言&#xff1f;它又有哪些獨特的特性和價值&#xff1f;本文將從四個方面、五個方面、六個方面和七…

精通推薦算法8:Embedding表征學習 -- 總體架構

1 Embedding表征學習的總體架構 目前&#xff0c;推薦算法精排模型大多基于Embedding MLP范式&#xff0c;模型底層是Embedding層&#xff0c;作用是將高維稀疏的輸入特征轉換為低維稠密的特征向量&#xff0c;并實現一定的模糊查找能力。模型上層是MLP層&#xff0c;作用是對…

在鯤鵬服務器上安裝nginx

華為鯤鵬服務器采用華為自研cpu ARMv8架構,提供 Windows 和多個Linux 系統 常使用 CentOS 7.6 64bit with ARM Nginx 和 Apache 一樣都是一種 Web 服務器。是基于 REST 架構風格&#xff0c;以統一資源描述符URI 或者統一資源定位符URL 作為溝通依據&#xff0c;通過 HTTP 協議…