pyhton基礎【20】面向對象進階一

目錄

一.進階

類方法和靜態方法

屬性(Properties)

繼承和多態

抽象基類(Abstract Base Classes - ABCs)

魔術方法(Magic Methods)

組合和聚合

使用場景

二.私有屬性

實現對數據的隱藏

設置私有屬性

添加額外對屬性操作的方法

三.私有方法

實現對方法的隱藏

直接調用私有方法所出現的問題

四.對象關聯

將兩個對象關聯

調用關聯的對象

關聯多個對象


一.進階

在Python中,面向對象編程(OOP)的進階概念允許開發者構建更復雜、更靈活和易于維護的代碼結構,以下是一些關鍵的進階特性及其應用。

類方法和靜態方法
  • 類方法(class methods):?
  1. 使用@classmethod裝飾器定義。
  2. 第一個參數通常是cls,指的是類本身,而非類的實例。
  3. 可以訪問和修改類狀態。
  • 靜態方法(static methods):?
  1. 使用@staticmethod裝飾器定義。
  2. 不需要默認的self或cls參數。
  3. ?主要用于在類的定義中包含一些與類相關,但在執行時不需要類或實例本身的工具函數。
屬性(Properties)

屬性允許將方法調用封裝成對屬性的訪問操作,使用@property裝飾器可以將類中的方法變為只讀屬性。

繼承和多態
  • 多重繼承(multiple inheritance):?
  1. Python支持從多個基類繼承,這允許創建復雜的繼承結構。
  2. 需要注意的是多重繼承可能導致的鉆石問題(Diamond Problem)及其解決方案:方法解析順序(MRO)。
  • 多態(polymorphism):?
  1. Python的多態性是通過鴨子類型(Duck Typing)來實現的:如果它像鴨子一樣走路和叫,那么它就是鴨子。
  2. 這意味著函數或方法可以接受任何類型的對象,只要這些對象提供了合適的方法或行為。
抽象基類(Abstract Base Classes - ABCs)
  • 抽象基類是一種定義了一組方法和屬性的基類,但至少有一個方法是抽象的。即:該方法沒有實現,僅有聲明。
  • 使用模塊abc和裝飾器@abstractmethod來定義抽象方法。
魔術方法(Magic Methods)
  • 通過定義特定的方法,可以改變類的一些默認行為,這些特定方法被稱為魔術方法。如:__init__, __str__, __call__等。
  • 例如:通過定義__add__方法,可以讓類的實例支持加法操作符。
組合和聚合
  • 組合(composition)和聚合(aggregation)是將對象或類聯合在一起的兩種方式,通常用于實現has-a關系。
  • 組合意味著一個對象完全擁有另一個對象,而聚合則允許對象有更獨立的生命周期。
使用場景

這些進階特性在許多場合都非常有用,例如:

  • 設計模式的實現:單例模式、工廠模式、策略模式等。
  • 構建框架或庫,封裝復雜的邏輯。
  • 處理復雜的數據結構,如圖、樹,和更高級的集合類型。
  • 提供API時隱藏內部實現的細節,僅暴露簡潔的接口。

掌握Python中的面向對象編程的進階概念,可以幫助開發者在編寫Python代碼時具備更高的靈活性和表達能力,構建出更加健壯、可重用和易于維護的軟件。

二.私有屬性

案例演示

class Cat:def __init__(self, new_name, new_age):self.name = new_nameself.age = new_agedef print_info(self):print("我叫%s,今年%s了" % (self.name, self.age))# 創建貓對象
cat = Cat("波斯貓", 4)
# 調用方法
cat.print_info()
# 嘗試修改屬性
cat.age = -10
# 調用方法
cat.print_info()

如果運行上述代碼,會發現,第二次輸出的信息有誤:我叫波斯貓,今年-10歲了

之所以出現這樣的錯誤,究其原因是因為:我們通過對象直接給實例屬性賦值的這種方式容易出錯

如果在賦值的時候,是通過一個實例方法的調用,在方法中對數據進行嚴格的檢查,合格的數據可以給屬性設置,不合格的數據就提醒開發者,這樣一來就能夠保證數據的準確性了。

那該怎樣實現呢?

實現對數據的隱藏

答:

1. 設置屬性為私有屬性

2. 添加額外對屬性操作的方法

設置私有屬性

在Python中,如果想要設置為私有的屬性,那么僅僅需要在定義屬性時在前面加兩個下劃線__即可

既然有了私有屬性,那對象能夠直接操作它么?

答:不能,否則就沒有私有的作用了

示例如下:

class Teacher:def __init__(self):self.name = "小明"self.__age = 18  # 這個屬性就是私有屬性t = Teacher()
print(t.name)  # 能夠獲取
print(t.__age)  # 此時會程序報錯,因為__age是私有屬性,不能通過對象直接操作
添加額外對屬性操作的方法

想要實現對私有屬性的操作,我們需要定義方法,在方法中操作

示例如下:

class Teacher:def __init__(self):self.name = "小明"self.__age = 18  # 這個屬性就是私有屬性def set_age(self, new_age):if 1 <= new_age <= 120:self.__age = new_ageprint("設置年齡成功")else:print("年齡數據有誤...")def get_age(self):return self.__aget = Teacher()
t.set_age(20)  # 設置年齡
print(t.get_age())  # 獲取年齡

簡單總結

1.操作屬性有兩種方法:

  • 直接通過對象修改:對象名.屬性名 = 數據
  • 通過方法間接修改:對象名.方法名(數據)

2.通過使用方法來進行修改,就可以在方法中進行數據合法性的檢查

3.通過__可以將屬性變為私有屬性,這樣就防止了通過對象直接操作屬性時可能帶來的隱患

三.私有方法

引入

生活中我們肯定去過銀行辦理過業務,我們可以從銀行的大門進入大廳,取號等待辦理業務,可以在大廳里來回走動,這個區域是所有人都可以隨意進出的。而銀行辦公人員工作的地方,只能有相應的權限的辦公人員才能進出,這個區域對于外來辦理業務的人員來說是禁止的。

通過上述的描述,大家能夠理解了一件事情,即訪問的地方不同需要的權限不同

那么試想,一個較大軟件系統肯定有很多個可以讓用戶直接調用的接口(API可以簡單理解為方法)這些接口可以任意調用,而有些接口就不能使用。

Python中,我們把可以通過對象直接調用的方法叫做公有方法,不能通過對象直接調用的方法叫做私有方法

實現對方法的隱藏

對于定義私有方法的方式與定義私有屬性基本相同,就是在方法的前面添加__(即兩個下劃線__)

示例如下:

class BankService:def __init__(self, money=5000):self.money = moneydef __bank_to_bank(self):if self.money >= 5000:print("這里是銀行之間的轉賬代碼...")return Trueelse:return Falsedef transfer(self):if self.money > 10000:if self.__bank_to_bank():print("轉賬成功...")else:print("轉賬失敗...")else:print("都沒錢,還轉什么啊!自己留著花吧!")bank_service = BankService(10001)
bank_service.transfer()  # 可以調用,是公有方法運行測試(轉賬成功):這里是銀行之間的轉賬代碼...
轉賬成功...運行測試(轉賬失敗):都沒錢,還轉什么啊!自己留著花吧!

注意點:Python中沒有像C++中public和private這些關鍵字來區別公有和私有,它是以命名方式來區分。如果在名字前面加了兩個下劃線__,則表明該屬性是私有,否則為公有。

直接調用私有方法所出現的問題

代碼示例:

上述代碼  加入bank_service.__bank_to_bank()  # 不可以調用,是私有方法運行結果:
Traceback (most recent call last):File "/Users/poppies/Documents/python_code/私有方法代碼測試.py", line 25, in <module>bank_service.__bank_to_bank()  # 不可以調用,是私有方法
AttributeError: 'BankService' object has no attribute '__bank_to_bank'
四.對象關聯

概述

我們在上學的時候,每個同學是一個對象,那么教室也是一個對象。每個同學肯定是屬于某一個教室的,例如張三是爬蟲一班的。那么怎樣才能用代碼來實現他們之間的關系呢?

將兩個對象關聯

如果當前的教室對象與學生對象是沒有任何關系關聯的。如果想要實現學生屬于教室,那么只需要兩步就能實現

  1. 搞清楚誰屬于誰,例如上述示例中,學生屬于教室
  2. 在范圍大的那個對象中,定義一個屬性存儲范圍小的對象引用即可

?代碼示例:

class ClassRoom:def __init__(self, name):self.cls_name = nameclass Student:def __init__(self, name):self.stu_name = name# 創建一個教室對象
room_1 = ClassRoom("python一班")# 創建一個學生對象
stu_1 = Student("安娜")# 直接給教室對象添加屬性
room_1.stu_obj = stu_1
調用關聯的對象

上述代碼已經完成了對象學生與教室的關聯,那么怎樣調用呢?格式如下:

# 如果A對象中的某個屬性指向了B對象,那么調用方式
A.xxx  # 此時就是指的B對象# 如果想要調用B對象中的某方法,那么就再接著.yyy方法即可
A.xxx.yyy()

代碼示例:

class ClassRoom:def __init__(self, name):self.cls_name = nameself.stu_obj = None  # 一般情況下在本類的其它方法中用到的實例屬性,都要在__init__方法中定義def add_new_stu(self, stu):"""定義新方法用來完成關聯"""self.stu_obj = stuclass Student:def __init__(self, name):self.stu_name = name# 創建一個教室對象
room_1 = ClassRoom("python一班")# 創建一個學生對象
stu_1 = Student("安娜")# 調用方法將學生添加到對象中
room_1.add_new_stu(stu_1)# 調用學生的姓名
# 教室對象.學生.姓名
print(room_1.stu_obj.stu_name)運行結果:
安娜
關聯多個對象

既然關聯一個對象搞懂了,那么關聯多個也就手到擒來,方式如下:

  1. 在范圍大的那個對象中再定義一個新的屬性,通過設置屬性指向新的對象
  2. 如果關聯的新的對象與之前關聯的對象類型相同,可以考慮用列表、字典、集合等方式將它們關聯

實現將多個學生關聯到一個教室:

class ClassRoom:def __init__(self, name):self.cls_name = nameself.stu_list = list()def add_new_stu(self, stu):self.stu_list.append(stu)class Student:def __init__(self, name):self.stu_name = name# 創建一個教室對象
room = ClassRoom("python爬蟲班")# 創建多個學生對象
stu_1 = Student("安娜")
stu_2 = Student("小明")
stu_3 = Student("小紅")# 調用方法將學生添加到對象中
room.add_new_stu(stu_1)
room.add_new_stu(stu_2)
room.add_new_stu(stu_3)# 調用學生的姓名
# 教室對象.列表[下標].姓名
print(room.stu_list[0].stu_name)
print(room.stu_list[1].stu_name)
print(room.stu_list[2].stu_name)

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

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

相關文章

滲透信息收集- Web應用漏洞與指紋信息收集以及情報收集

目錄 1. 整體流程與目標概述 2. 常用工具及其用途 2.1 掃描與枚舉工具 2.2 情報與數據聚合工具 2.3 流量攔截與手工驗證工具 3. 詳細技術手法與步驟 3.1 準備階段 3.2 主動掃描與指紋識別 3.3 數據交叉驗證與漏洞確認 3.4 進一步滲透與隱蔽操作 4. 實際工作經驗與注…

ASP.NET代碼審計 MVC架構 SQL注入漏洞n

接口路由 /Maintenance/GetMaintenanceList MaintenanceController.cs代碼 Maintenance 控制器里面的 GetMaintenanceList 方法 接收參數 id 傳進 MaintenanceManager.GetMaintenanceList 方法調用 MaintenanceManager.cs代碼 這里 id 和 faultId 不一樣是不影響的 C# 按順序匹…

Python入門Day4

Python中數據的常用操作 數據拷貝 根據以下代碼可以看出l1和l2實際上都是對于數據的引用&#xff0c;當l1被改變了&#xff0c;l2也會發生同樣的改變&#xff0c;l2 l1只是將l2指向了l1所指向的地址。 >>> l1 [1,2,[3,4],[5,6]] >>> l2 l1 >>>…

計算機網絡中的常用表項梳理

核心表項對比 表項 全稱 工作層級 主要功能 涉及設備 典型生命周期 MAC表 媒體訪問控制表 數據鏈路層&#xff08;二層&#xff09; Mac地址和端口關系 交換機、網橋 動態學習 FDB表 轉發數據庫 &#xff08;Forwarding DataBase&#xff09; 數據鏈路層&#xf…

百度輪崗:任命新CFO,崔珊珊退居業務二線

文 | 大力財經2025 年 7 月 1 日&#xff0c;百度組織再次變革&#xff0c;崔珊珊退居二線引發的行業關注。百度創始人李彥宏發布的內部信&#xff0c;宣布的新一輪組織調整里&#xff0c;崔珊珊退居二線這一變動&#xff0c;格外引人矚目。崔珊珊&#xff0c;這位在百度人力資…

TAMPER-RTC(STM32F103) 引腳說明

我來查看ST官方手冊中關于TAMPER-RTC引腳的具體說明。 Ran tool Ran tool Ran tool Read file: doc/STM32F103VGT6/STM32F103VGT6_specification.txt Read file: doc/STM32F103VGT6/STM32F103VGT6_specification.txt Ran tool Read file: doc/STM32F103VGT6/STM32F103VGT6_spec…

BUUCTF在線評測-練習場-WebCTF習題[極客大挑戰 2019]HardSQL1-flag獲取、解析

解題思路 打開靶場、熟悉的感覺 上次是過濾了很多字符&#xff0c;用了雙寫繞過進行注入即可&#xff0c;這次進階了難度 先老規矩判斷下閉合 11 123 報錯提示 You have an error in your SQL syntax; check the manual that corresponds to your MariaDB server version…

MyBatis動態SQL進階:復雜查詢與性能優化實戰

引言 在復雜業務場景中&#xff0c;SQL查詢往往需要動態拼接條件、復用代碼片段&#xff0c;并支持批量操作。MyBatis的動態SQL功能提供了強大的解決方案&#xff0c;本文將深入解析<choose>條件分支、<sql>片段復用、批量操作優化等核心技巧&#xff0c;助你寫出高…

@Transactional 注解失效的場景及原因分析

先分析一下 1&#xff0c;內部調用&#xff0c;原對象調用&#xff0c;不是代理對象調用 2&#xff0c;private方法&#xff0c;源碼中&#xff0c;只能是public方法 3&#xff0c;異常被捕獲了&#xff0c;事物攔截器&#xff0c;無法感知 4&#xff0c;子線程調用&#x…

使用unity創建項目,進行動畫制作

1. 創建unity項目 error: error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/PlasticSCM/log4netPlastic.dll could not be found error CS0006: Metadata file Library/PackageCache/com.unity.collab-proxy2.8.2/Lib/Editor/Plasti…

Centos系統及國產麒麟系統設置自己寫的go服務的開機啟動項完整教程

1、創建服務文件 在 /etc/systemd/system/ 下新建服務配置文件&#xff08;需sudo權限&#xff09;&#xff0c;例如&#xff1a; sudo nano /etc/systemd/system/mygo.service 如下圖&#xff0c;創建的mygo.service 2、創建內容如下&#xff1a; DescriptionThe go HTTP a…

Java面試寶典: IO流

1. 下面哪個流類屬于面向字符的輸入流() 選項: A. BufferedWriter B. FileInputStream C. ObjectInputStream D. InputStreamReader 答案:D 詳細分析: 字符流與字節流的本質區別: 字符流(Character Streams)以Unicode字符為單位操作數據,適用于文本處理字節流(Byte…

黑馬python(二十五)

目錄&#xff1a;1.數據輸出-輸出為Python對象2.數據輸出-輸出到文件中3.綜合案例1.數據輸出-輸出為Python對象2.數據輸出-輸出到文件中移動文件到文件夾&#xff1a;生成了好多文件&#xff0c;因為Rdd是有分區的 &#xff0c;會把數據分散到各個分區去存儲&#xff0c;因為電…

【LeetCode 熱題 100】41. 缺失的第一個正數——(解法一)暴力解

Problem: 41. 缺失的第一個正數 題目&#xff1a;給你一個未排序的整數數組 nums &#xff0c;請你找出其中沒有出現的最小的正整數。 請你實現時間復雜度為 O(n) 并且只使用常數級別額外空間的解決方案。 文章目錄整體思路完整代碼時空復雜度時間復雜度&#xff1a;O(N log N)…

在運行 Laravel Sail 前,需安裝 Docker Desktop 并完成基礎配置/具體步驟

一、安裝 Docker Desktop&#xff08;必備環境&#xff09; Windows 系統 &#xff08;windows安裝包 有兩個版本&#xff09; 架構版本查看 1. Win R? 輸入 ?cmd? 打開命令提示符&#xff1b; 2. ?輸入命令?&#xff1a; bash echo %PROCESSOR_ARCHITECTURE% 3. ?結果…

AI 應用于進攻性安全

一、引言 大語言模型&#xff08;LLM&#xff09;和 AI 智能體的出現推動進攻性安全變革&#xff0c;其在偵察、掃描、漏洞分析、利用、報告五個階段展現出數據分析、代碼生成、攻擊場景規劃等能力&#xff0c;能提升安全團隊效率與擴展性&#xff0c;但存在 “幻覺” 等局限性…

微控制器中的EXTI0(External Interrupt 0)中斷是什么?

微控制器中的EXTI0(External Interrupt 0)中斷是什么? EXTI0(External Interrupt 0) 是微控制器(如STM32等ARM Cortex-M系列芯片)中的一個外部中斷線,專門用于處理來自特定GPIO引腳的外部信號觸發中斷。以下是詳細說明: 1. 基本概念 EXTI(External Interrupt/Event …

EasyGBS平臺內置AI算法了,算法成為了視頻平臺的標配

今年五一的時候立了個flag&#xff08;《國標GB28181平臺EasyGBS未來研發方向在哪&#xff1f;》&#xff09;&#xff0c;我想不能再局限在只是滿足于傳統視頻平臺的功能&#xff0c;傳統的EasyGBS也就是接入幾種視頻協議&#xff0c;什么RTSP、ONVIF、RTMP、GB28181這些&…

C# 常量與變量

在 C# 中&#xff0c;常量和變量是存儲數據的基本方式&#xff1a; // 常量&#xff1a;使用 const 關鍵字聲明&#xff0c;必須在聲明時初始化&#xff0c;且值不能改變 const double Pi 3.14159; const string Message "Hello, World!"; ? // 變量&#xff1a;…

TensorRT-LLM:大模型推理加速的核心技術與實踐優勢

大型語言模型推理就像讓一頭300公斤的大熊貓玩平衡木——顯存消耗和計算效率這對雙胞胎問題隨時可能讓表演翻車。以主流的7B參數模型為例&#xff0c;FP16精度下僅模型權重就吃掉14GB顯存&#xff0c;這還沒算上推理過程中不斷膨脹的KV Cache——當處理2048長度的對話時&#x…