Python基礎20 面向對象(3)多態、封裝、反射

文章目錄

  • 一、多態
    • 1、什么是多態
    • 2、多態小實驗
  • 二、封裝
    • 1、什么是封裝
    • 2、內部屬性的約定
  • 三、反射
    • 1、什么是反射
    • 2、四個實現自省的函數
      • (1)hasattr(object,name)
      • (2)getattr(object,name,default=None)
      • (3)setattr(object,name,value)
      • (4)delattr(object,name)
    • 3、反射的用途
    • 4、動態導入模塊
  • 四、attr內置方法
    • 1、__getattr__()
    • 2、__delattr__()
    • 3、__setattr__()
  • 五、小實驗1:包裝標準類型
  • 六、小實驗2:組合方式完成授權,改寫文件處理函數

一、多態

1、什么是多態

多態是指對象通過他們共同的屬性和方法來操作及訪問,而不需要考慮他們具體的類。

s = "abc"
print(s.__len__())  # 3,等同len(s)l = [1, 3]
print(l.__len__())  # 2,等同len(l)

多態體現在由同一個類實例化出多個對象,這些對象執行相同的方法時,執行的過程和結果是不一樣的。

class H2O:def __init__(self, name, tem):self.name = nameself.tem = temdef turn(self):if self.tem > 100:print("%s 變成了水蒸氣" % self.name)elif self.tem < 0:print("%s 變成了冰" % self.name)else:print("%s 變成了水" % self.name)class Steam(H2O):pass
class Water(H2O):pass
class Ice(H2O):passs = Steam("s", 1000)
w = Water("w", 50)
i = Ice("i", -10)s.turn()    # s 變成了水蒸氣
w.turn()    # w 變成了水
i.turn()    # i 變成了冰

2、多態小實驗

模擬 len() 函數,對上述turn方法,做成函數形式。

# 接上述實例化代碼后,補充如下代碼
def turn(obj):obj.turn()turn(s) # s 變成了水蒸氣
turn(w) # w 變成了水
turn(i) # i 變成了冰

二、封裝

1、什么是封裝

(1)裝,即把一些屬性裝到一個容器中。封,即為隱藏。
(2)類就是一種容器,這本身就是一種封裝。
(3)類中定義私有的屬性,只有類的內部可以使用,外部無法訪問。
(4)封裝明確區分內外,內部的實現邏輯,外部無法知曉,并且為封裝到內部的邏輯提供一個訪問接口給外部使用。

2、內部屬性的約定

python并沒有嚴格限制外部訪問內部屬性,但把單下劃線和雙下劃線開頭的屬性約定為內部屬性。

class People:_age = 18__sex = "f"def __init__(self):passdef info(self):print("age %s,sex %s" %(self._age, self.__sex))
p1 = People()
print(People._age)  # 18 但下劃線開頭屬性,外部可以直接訪問
print(People._People__sex)  # f 雙下劃線開頭屬性,會在屬性字典中重命名為_類__屬性
p1.info()   # age 18,sex f 內部可以調用它們

三、反射

1、什么是反射

反射主要是指程序可以訪問、檢測、和修改它本身狀態或行為的一種能力(自省)。

2、四個實現自省的函數

以下四個函數適用于類和對象。

(1)hasattr(object,name)

?判斷name是否在object中。

(2)getattr(object,name,default=None)

? 相當于執行object.name

(3)setattr(object,name,value)

? 設置object的屬性

(4)delattr(object,name)

?刪除object中的name屬性

class People:age = 18sex = "f"def __init__(self):self.age = self.agedef info(self):print("age %s,sex %s" % (self.age, self.sex))p1 = People()print(hasattr(p1, "age"))  # True 相當于判斷p1.age是否可以被調用
getattr(p1, "info")()  # age 18,sex f 相當于調用p1.info
# getattr(p1, "info1")()  # 沒有info1,則報錯
print(getattr(p1, "info1", 10)) # 10 沒有不報錯,返回默認值setattr(p1,"func",lambda x:x*2)
print(p1.func(3))   # 6
print(p1.__dict__)  # {'age': 18, 'func': <function <lambda> at 0x000001623A680160>}
delattr(p1,"age")   # 刪除age屬性
print(p1.__dict__)  # {'func': <function <lambda> at 0x000001623A680160>}

3、反射的用途

可以事先定義接口,接口只有在被完成后才會真正執行,這實現了即插即用。
prog1代碼:

class Ftp:def __init__(self):passdef put(self):print("執行put方法")

調用程序代碼:

from prog1 import Ftp
f1 = Ftp()if hasattr(f1,"put"):func_get = getattr(f1,"put")func_get()
else:print("執行其他邏輯")

4、動態導入模塊

動態導入模塊就是基于反射實現的。
t.py代碼:

def test1():print("I am test1")def _test2():print("I am test2")

執行模塊代碼:

module_t = __import__("d1.t")   # d1與執行模塊在同級目錄,t為d1的子文件
print(module_t) # <module 'd1' (namespace)>
module_t.t.test1()  # I am test1
from d1.t import *
_test2()  #報錯
from d1.t import test1,_test2
_test2()    #不報錯
from d1 import t
t._test2() # 不報錯
import importlib
m = importlib.import_module("d1.t")
m._test2() # 不報錯

四、attr內置方法

在不自定義這些內置方法時,程序會執行其自身的對應方法。

1、getattr()

在屬性不存在時,會自動觸發自定義的__getattr__()。屬性存在時,不執行它,而是執行其自身的方法。

class Foo:def __init__(self,y):self.y = ydef __getattr__(self, item):print("執行我")f1 = Foo(10)
print(f1.y) # 10
print(getattr(f1,"y")) # 10
f1.aa # 執行我

2、delattr()

執行 del 對象.屬性 時,會觸發 __delattr__()

class Foo:x = 1def __init__(self,y):self.y = ydef __delattr__(self, item):print("執行我")self.__dict__.pop(item)f1 = Foo(10)
print(f1.__dict__)  # {'y': 10}
del f1.y    # 執行我
print(f1.__dict__)  # {}

3、setattr()

在執行對象.屬性=value時,觸發 __setattr__()

class Foo:x = 1def __init__(self,y):passdef __setattr__(self, key, value):print("執行我")self.__dict__[key] = valuef1 = Foo(10)
print(f1.__dict__)  # {}
f1.y = 11   # 執行我
print(f1.__dict__)  # {'y': 11}

五、小實驗1:包裝標準類型

重寫列表類型:只能向列表中添加字符串元素;刪除元素后,要返回該元素值。

class List(list):def append(self, obj):if type(obj) is str:super().append(obj)else:print("必須是字符串")l = List("ab")
print(l)    # ['a', 'b']
l.append(1) # 必須是字符串
print(l)    # ['a', 'b']
l.append("c")
print(l)    # ['a', 'b', 'c']

六、小實驗2:組合方式完成授權,改寫文件處理函數

授權是包裝的一個特性。包裝一個類型通常是對已存在的類型的一些定制,這種做法可以新建,修改或刪除原有產品的功能,其他的則保持原樣。授權的過程是所有更新的功能都是由新類的某部分來處理,但已存在的功能就授權給對象為默認屬性。

實驗內容:寫入文件內容加時間。其他文件處理函數的功能不變。

import time
class FileHandle:def __init__(self,filename,mode="r",encoding="utf-8"):self.f = open(filename,mode,encoding=encoding)def write(self,content):t = time.strftime("%F %X")self.f.write("%s %s" %(t,content))def __getattr__(self, item):return getattr(self.f,item)f1 = FileHandle("a.txt","w+")
f1.write("內存空間不足!\n")
f1.write("磁盤空間不足!")
f1.seek(0)
print(f1.read())
f1.close()'''a.txt內容
2024-02-22 15:57:05 內存空間不足!
2024-02-22 15:57:05 磁盤空間不足!
'''

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

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

相關文章

神秘人暗訪:行政窗口為什么要開展神秘顧客調研

在競爭日益激烈的服務市場中&#xff0c;行政窗口作為公共服務的直接提供者&#xff0c;其服務質量的好壞直接關系到政府的形象和公眾對政府的信任度。為了更好地滿足市民的需求&#xff0c;提升服務質量&#xff0c;開展神秘顧客調查顯得尤為重要。神秘顧客調查的必要性包括以…

內網穿透的應用-如何本地部署Elasticsearch搜索分析引擎實現并發布公網遠程訪問

文章目錄 系統環境1. Windows 安裝Elasticsearch2. 本地訪問Elasticsearch3. Windows 安裝 Cpolar4. 創建Elasticsearch公網訪問地址5. 遠程訪問Elasticsearch6. 設置固定二級子域名 Elasticsearch是一個基于Lucene庫的分布式搜索和分析引擎&#xff0c;它提供了一個分布式、多…

探索Flask框架:打造優雅而強大的Web應用

在當今互聯網時代&#xff0c;Web應用的需求日益增長&#xff0c;而作為開發者&#xff0c;我們需要一個簡潔明快、靈活可擴展的框架來滿足這些需求。Flask框架作為一個Python微型框架&#xff0c;在其簡潔的設計理念和豐富的擴展生態系統之間找到了完美的平衡&#xff0c;為我…

洛谷--二分(Java實現)

洛谷 B3627 立方根 題目描述 給定正整數 n&#xff0c;求 √n?。答案向下取整。 輸入格式 僅一行&#xff0c;一個正整數 n。 輸出格式 僅一行&#xff0c;一個正整數&#xff0c;表示√n。向下取整輸出。 輸入輸出樣例 輸入 #1 27 輸出 #1 3 輸入 #2 100000 輸…

ORACLE之 decode函數

語法&#xff1a; DECODE(expression, search1, result1, search2, result2, ..., default_result) 其中&#xff0c;expression是要進行比較的表達式&#xff0c;search1, search2等是可能的值&#xff0c;result1, result2等是對應的結果。如果expression等于search1&#x…

Java類的成員、繼承、多態

當談論Java類的成員、繼承和多態時&#xff0c;我們談論的是面向對象編程的基本概念。讓我逐一介紹&#xff1a; 1. **成員**&#xff1a; - **字段&#xff08;Field&#xff09;**&#xff1a;也稱為屬性或變量&#xff0c;用于存儲對象的狀態信息。 - **方法&#xf…

防御保護第六次作業

需求: 8&#xff0c;分公司內部的客戶端可以通過域名訪問到內部的服務器 9&#xff0c;假設內網用戶需要通過外網的web服務器和pop3郵件服務器下載文件和郵件&#xff0c;內網的FTP服務器也需要接受外網用戶上傳的文件。針對該場景進行防病毒的防護。 10&#xff0c;我們需要針…

C++模板從入門到入土

1. 泛型編程 如果我們需要實現一個不同類型的交換函數&#xff0c;如果是學的C語言&#xff0c;你要交換哪些類型&#xff0c;不同的類型就需要重新寫一個來實現&#xff0c;所以這是很麻煩的&#xff0c;雖然可以cv一下&#xff0c;有了模板就可以減輕負擔。 下面寫一個適…

日常leetcode代碼思路總結(持續更新)

日常leetcode代碼思路總結&#xff08;持續更新&#xff09; 難易leecode題號題目描述思路簡單121. 買賣股票的最佳時機只準一次買賣0表示持有&#xff0c;1表示不持有&#xff1b;dp[0][i] max(dp[0][i-1], -prices[i])&#xff1b;dp[1][i] max(dp[1][i-1], dp[0][i] pric…

Openwrt刪除內核patch

環境說明 ubuntu-18.04 openwrt-21.02 安裝quilt sudo apt install quilt quilt指令說明 Usage: quilt [--trace[=verbose]] [--quiltrc=XX] command [-h] ...quilt --version Commands are:add fold mail refresh snapshotannotate fork new rem…

基于springboot+vue的中小企業設備管理系統(前后端分離)

博主主頁&#xff1a;貓頭鷹源碼 博主簡介&#xff1a;Java領域優質創作者、CSDN博客專家、阿里云專家博主、公司架構師、全網粉絲5萬、專注Java技術領域和畢業設計項目實戰&#xff0c;歡迎高校老師\講師\同行交流合作 ?主要內容&#xff1a;畢業設計(Javaweb項目|小程序|Pyt…

H 橋逆變方式介紹(雙極性)

單極性控制和雙極性控制是說IGBT四個管子的控制 前面所說的單極性控制是其中一個管子開通、關閉另外一個管子持續開通 而雙極性是四個管子中的兩個管子同時導通&#xff0c;同時關斷。彼此交替變化 所以當方波出現低電平時&#xff0c;是一對管子同時導通&#xff0c;出現高電…

2.21 Qt day2 菜單欄/工具欄/狀態欄/浮動窗口、UI界面、信號與槽

思維導圖 使用手動連接&#xff0c;將登錄框中的取消按鈕使用qt4版本的連接到自定義的槽函數中&#xff0c;在自定義的槽函數中調用關閉函數 將登錄按鈕使用qt5版本的連接到自定義的槽函數中&#xff0c;在槽函數中判斷ui界面上輸入的賬號是否為"admin"&#xff0c;…

成像光譜遙感技術中的AI革命:ChatGPT應用指南

“成像光譜遙感技術中的人工智能革命&#xff1a;ChatGPT應用指南”&#xff0c;這是一門旨在改變您使用人工智能處理遙感數據的方式。將最新的人工智能技術與實際的遙感應用相結合&#xff0c;提供不僅是理論上的&#xff0c;而且是適用和可靠的工具和方法。無論你是經驗豐富的…

golang實現延遲隊列(delay queue)

golang實現延遲隊列 1 延遲隊列&#xff1a;郵件提醒、訂單自動取消 延遲隊列&#xff1a;處理需要在未來某個特定時間執行的任務。這些任務被添加到隊列中&#xff0c;并且指定了一個執行時間&#xff0c;只有達到指定的時間點時才能從隊列中取出并執行。 應用場景&#xff1…

智慧驛站_智慧文旅驛站_輕松的驛站智慧公廁_5G智慧公廁驛站_5G模塊化智慧公廁

多功能城市智慧驛站是在智慧城市建設背景下&#xff0c;所涌現的一種創新型社會配套設施。其中&#xff0c;智慧公廁作為城市智慧驛站的重要功能基礎&#xff0c;具備社會配套不可缺少的特點&#xff0c;所以在應用場景上&#xff0c;擁有廣泛的需求和要求。那么&#xff0c;城…

高企認定的官方費用

高新技術企業認定并沒有直接的“官費”&#xff0c;但是在申請高新技術企業認定過程中&#xff0c;企業可能會涉及到一些與政府部門相關的費用&#xff0c;主要包括以下幾種情況&#xff1a; 1.知識產權相關費用&#xff1a;?申請專利、軟件著作權等知識產權時需要向國家知識…

#12解決request中getReader()和getInputStream()只能調用一次的問題

目錄 1、背景 2、解決方案 2.1、自定義HttpServletRequestWrapper 2.2、JsonRequestHeaderParamsHelper 2.3、HttpServletRequestReplacedFilter 2.4、使用 1、背景 當前系統Content-Type為application/json&#xff0c;參數接收方式采用RequestBody和RequestParam&#…

平時積累的FPGA知識點(10)

平時在FPGA群聊等積累的FPGA知識點&#xff0c;第10期&#xff1a; 41 ZYNQ系列芯片的PL中使用PS端送過來的時鐘&#xff0c;這些時鐘名字是自動生成的嗎&#xff1f; 解釋&#xff1a;是的。PS端設置的是ps_clk&#xff0c;用report_clocks查出來的時鐘名變成了clk_fpga_0&a…

vue系列--通過js生成前端水印的方法

此方法開箱即用&#xff0c;在vue項目中import即可。 例如&#xff1a; //在vue組件中 import Watermark from /utils/watermark.js//在methods中 Watermark.set({color:"",text:""})//設置水印Watermark.remove() //刪除水印 const watermark {}const…