python面向對象之魔術方法(特定時機自動觸發) 魔術屬性

来源:https://www.cnblogs.com/shuaiyao666/archive/2022/03/30/16079785.html
-Advertisement-
Play Games

魔術方法(特定時機自動觸發) __init__ 構造方法 觸發時機:實例化對象,初始化的時候觸發 功能:為對象添加成員 參數:參數不固定,至少一個self參數 返回值:無 # (1) 基本語法 class MyClass(): def __init__(self): print("構造方法被觸發 . ...


魔術方法(特定時機自動觸發)

 

__init__ 構造方法

觸發時機:實例化對象,初始化的時候觸發
功能:為對象添加成員
參數:參數不固定,至少一個self參數
返回值:無

# (1) 基本語法
class MyClass():
    def __init__(self):
        print("構造方法被觸發 ... ")
        self.color = "屎黃色"
        
# 實例化對象
obj = MyClass()
print(obj.__dict__)
print(obj.color)

# (2) 帶有多個參數的構造方法
class MyClass():
    def __init__(self,color):
        self.color = color

# 實例化對象
obj1 = MyClass("狗屎綠")
print(obj1.color)
obj2 = MyClass("粉嫩紅")
print(obj2.color)

# (3)類可以是一個,對象可以是多個,創造的對象彼此是獨立的;
class Children():
    def __init__(self,name,skin):
        self.name = name
        self.skin = skin
    
    def cry(self):
        print("小孩一下生久哇哇哇的哭")
    
    def la(self):
        print("小孩一下生久拉粑粑")
        
    def __eat(self):
        print("小孩一下生就要吃奶奶..")
    
    def info(self):
        print("小孩的名字:{},小孩的膚色{}".format(self.name,self.skin))
        
    def info2(self,name,skin):
        print("小孩的名字:{},小孩的膚色{}".format(name,skin))


# 實例化對象
afanda = Children("阿凡達","深藍色")
afanda.cry()
afanda.info()

haoke = Children("綠巨人","綠色的")
haoke.la()
haoke.info()

wangbaoqiang = Children("王寶強","亮綠色")
wangbaoqiang.info()
# wangbaoqiang.__eat() error
wangbaoqiang.info2("張保張","黃色")
View Code

 

__new__ 魔術方法

觸發時機:實例化類生成對象的時候觸發(觸發時機在__init__之前)
功能:控制對象的創建過程
參數:至少一個cls接受當前的類,其他根據情況決定
返回值:通常返回對象或None

 

(1) 基本使用

class MyClass2():
    a = 100
obj2 = MyClass2()
# print(obj2)

class MyClass1():
    def __new__(cls):
        # print(cls)        
        # 1.返回本類對象
        """類.成員方法(類)"""
        # return object.__new__(cls)
        # 2.返回其他類的對象
        # return obj2
        # 3.不返回對象,None
        return None        
    
obj = MyClass1()
# print(obj.a)
print(obj)
View Code

(2) __new__ 觸發時機要快於 __init__

"""
__new__  創建對象
__init__ 初始化對象
"""
class MyClass():

    def __new__(cls):
        print(1)
        return object.__new__(cls)

    def __init__(self):
        print(2)
    
obj = MyClass()    
View Code

(3) __new__的參數要和__init__參數一一對應

class Boat():
    def __new__(cls,name):
        return object.__new__(cls)
    
    def __init__(self,name):
        self.name  = name

obj = Boat("萬里陽光號")
print(obj.name)
View Code

使用收集參數進行改造

class Boat():
    # *args,**kwargs 可以收集多餘的所有參數
    def __new__(cls,*args,**kwargs):
        return object.__new__(cls)
    
    def __init__(self,name,type):
        self.name  = name
        self.type = type

obj = Boat("萬里陽光號","破木頭做的")
print(obj.name , obj.type)
View Code

(4) __new__和__init__之間的註意點

如果__new__ 沒有返回對象或者返回的是其他類的對象,不會調用構造方法.
只有在返回自己本類對象的時候,才會調用構造方法.

class Children():
    def __new__(cls,*args,**kwargs):
        return obj2
        # pass
        
    def __init__(self,name,skin):
        print("構造方法被觸發 ... ")
        # self.name = name
        # self.skin = skin
        
obj = Children("滅霸","紫薯")

# print(obj.name) error
# print(obj.skin) error
View Code

 

 

__del__ 魔術方法(析構方法)

觸發時機:當對象被記憶體回收的時候自動觸發[1.頁面執行完畢回收所有變數 2.所有對象被del的時候]
功能:對象使用完畢後資源回收
參數:一個self接受對象
返回值:無

(1) 基本語法

class Lion():
    def __init__(self,name):
        self.name = name
        
    def __del__(self):
        print("析構方法被觸發 ... ")

# 觸發方式一: 頁面執行完畢回收所有變數
obj1 = Lion("辛巴")

# 觸發方式二: 所有對象被del的時候
obj2 = obj1
obj3 = obj1
print(obj2 , obj1 ,obj3)
print("<====start===>")
del obj1
del obj2
del obj3
print("<====end===>")
View Code

(2) 模擬文件操作

import os
class ReadFile():
    # 根據文件是否存在,創建對象
    def __new__(cls,filename):
        if os.path.exists(filename):
            return object.__new__(cls)
        else:
            print("抱歉,沒有這個文件")
    
    # 打開文件
    def __init__(self,filename):
        self.fp = open(filename,mode="r",encoding="utf-8")
        
    # 關閉文件
    def __del__(self):
        self.fp.close()
        
    # 讀取文件
    def readcontent(self):
        return self.fp.read()
        

obj = ReadFile("0.py")
print(obj.readcontent())
View Code

 

__str__ 魔術方法

觸發時機: 使用print(對象)或者str(對象)的時候觸發
功能: 查看對象
參數: 一個self接受當前對象
返回值: 必須返回字元串類型

class Cat():
    gift = "抓老鼠"
    def __init__(self,name):
        self.name = name
        
    def cat_gift(self):
        return "小貓叫{},小貓會{}".format(self.name,self.gift)
    
    def __str__(self):
        return self.cat_gift()    

    __repr__ = __str__
    
tom = Cat("湯姆")
# 觸發時機1 :  print(對象)
# print(tom)
# 觸發時機2 :  str(對象)
res = str(tom)
print(res)

print("<==================>")
res = repr(tom)
print(res , type(res))
print("<==================>")
View Code

 

__repr__ 魔術方法

觸發時機: 使用repr(對象)的時候觸發
功能: 查看對象,與魔術方法__str__相似
參數: 一個self接受當前對象
返回值: 必須返回字元串類型

class Mouse():
    gift = "偷油吃"
    def __init__(self,name):
        self.name = name
    
    def mouse_gift(self):
        return "老鼠叫{},老鼠會{}".format(self.name,self.gift)
    
    def __repr__(self):
        return self.mouse_gift()
    
    # 系統底層預設把__repr__方法賦值給__str__方法,所以通過print或者str強轉可以觸發;
    # __str__ = __repr__
    
jerry = Mouse("傑瑞")
# res = repr(jerry)
# print(res)

# 可以觸發
# print(jerry)
res = str(jerry)
print(res)
View Code

 

__call__ 魔術方法

觸發時機:把對象當作函數調用的時候自動觸發
功能: 模擬函數化操作
參數: 參數不固定,至少一個self參數
返回值: 看需求

 

(1) 基本語法

 

class MyClass():
    def __call__(self):
        print("__call__魔術方法被觸發 ... ")

obj = MyClass()
obj()

 

(2) 利用__call__魔術方法做統一調用

class Wash():
    def __call__(self,something):
        print("我要洗{}".format(something))
        self.step1(something)
        self.step2()
        self.step3()
        return "洗完了"
        
    def step1(self,something):
        print("放水,把{}扔進去".format(something))
        
    def step2(self):
        print("倒洗衣粉,洗衣液,藍月亮,金紡,立白 ... ")
        
    def step3(self):
        print("洗一洗,晾乾,穿上")

obj = Wash()
# obj.step1()
# obj.step2()
# obj.step3()
res = obj("襪子")
print(res)
View Code

 

 (3) 模擬整型強轉操作

import math
class MyInt():
    def __call__(self,num):
        if isinstance(num,bool):
            if num == False:
                return 0 
            else:
                return 1
                
        elif isinstance(num,int):
            return num
            
        elif isinstance(num,float):
            # 方法一
            # a,b = str(num).split(".")
            # return eval(a)
            
            # 方法二
            """
            if num >= 0:
                return math.floor(num)
            else :
                return math.ceil(num)
            """
            # 簡寫
            return math.floor(num) if  num >= 0  else math.ceil(num)
            
        elif isinstance(num,str):
            if (num[0] == "+" or num[0] == "-") and num[1:].isdecimal():
                # 獲取當前字元串的正負值
                if num[0] == "+":
                    sign = 1
                elif num[0] == "-":
                    sign = -1    
                # 截取符號後面的字元串傳遞
                return self.calc(num[1:],sign)
                
            elif num.isdecimal():
                return self.calc(num)
            else:
                return "這個算不了兄弟~"

        
    # 計算最後的數值
    def calc(self,num,sign=1):
        # 去掉前面的"0"字元串
        num    = num.lstrip("0")
        # print(num , type(num) , "<==============>")
        if num == "":
            return 0 
        
        return eval(num) * sign            
            
    
myint = MyInt()
res = myint(-5.67) 
print(res , type(res))
res = myint("-000000000000055555")
print(res , type(res))
res = myint("asdfasdfasdfasdf")
print(res , type(res))
# print(myint("+0000000000000"))
# bool int  float 純數字字元串

# int(3.78) => 3
# print(int(-3.78))
# import math
# print(math.floor(0) ) # => 3
# print(math.ceil(0))

"""
print(    int("00000000000001223")   )  # 1223
print(    int("-00000000000001223")   ) # -1223
print(    int("+00000000000001223")   ) # 1223
print(    int("+0000000000000")   ) # 1223
"""
# print(    int("asdfasdfasdfasdf")   ) # 1223
# print(  eval("00000000000001223")   )
# print(  eval("+00000000000001223")   )
# print(  eval("-00000000000001223")   )
# print(  eval("-00000000000001223abc")   )
View Code

 

----普通變數的基本操作,如果應用在對象上,也有相應的魔術方法

__bool__ 魔術方法

觸發時機:使用bool(對象)的時候自動觸發
功能:強轉對象
參數:一個self接受當前對象
返回值:必須是布爾類型

 

類似的還有如下等等(瞭解):
__complex__(self) 被complex強轉對象時調用
__int__(self) 被int強轉對象時調用
__float__(self) 被float強轉對象時調用
...
...

 

基本語法

class MyClass():
    def __bool__(self):
        return True
obj = MyClass()
print(bool(obj))

 

__add__ 魔術方法  (與之相關的__radd__ 反向加法)

觸發時機:使用對象進行運算相加的時候自動觸發
功能:對象運算
參數:二個對象參數
返回值:運算後的值

 

類似的還有如下等等:
__sub__(self, other)          定義減法的行為:-
__mul__(self, other)          定義乘法的行為:
__truediv__(self, other)     定義真除法的行為:/
...
...

 基本語法

class MyClass():
    def __init__(self,num):
        self.num = num
        
    # 當對象在 + 號的左側時,自動觸發
    def __add__(self,other):
        # print(self)
        # print(other)
        return self.num * 3 + other
        
    def __radd__(self,other):
        # print(self)  # 對象
        # print(other) # 7
        return self.num * 5 + other
        
# add的觸發方式
a = MyClass(3)
res = a + 1
print(res)

# radd的觸發方式
b = MyClass(5)
res = 7 + b
print(res)

# 對象 + 對象
res = a + b
print(res)

"""
a+b 觸發的是add魔術方法  self 接受的是a   other 接受的是b
return a.num + b  => return 9 + b
res =  9 + b   觸發的是radd魔術方法  self 接受的是b   other 接受的是9
return b.num * 5 + 9  => 5 * 5 + 9 => 34
"""
View Code

 

__len__ 魔術方法

觸發時機:使用len(對象)的時候自動觸發
功能:用於檢測對象中或者類中某個內容的個數
參數:一個self接受當前對象
返回值:必須返回整型

 

類似的還有如下等等(瞭解):
__iter__(self) 定義迭代容器中的元素的行為
__reversed__(self) 定義當被 reversed() 調用時的行為
__contains__(self, item) 定義當使用成員測試運算符(in 或 not in)時的行為
...
...

 

len(對象) => 類中的所有自定義成員

 

class MyClass():
    pty1 = 1
    pty2 = 2 
    __pty3 = 3
    
    def func1():
        pass
    def func2():
        pass
    def __func3():
        pass
        
    def __len__(self):
        # 以__開頭並且以__結尾的成員過濾掉;
        return len( [  i for i in MyClass.__dict__ if not (  i.startswith("__") and i.endswith("__")  )  ] ) 

obj = MyClass()
print(len(obj))


"""
代碼原型;
print(MyClass.__dict__)
lst = []
for i in MyClass.__dict__:
    print(i , type(i))
    if not (  i.startswith("__") and i.endswith("__")  ):
        lst.append(i)
print(len(lst))
"""

"""

{
'__module__': '__main__', 
'pty1': 1, 
'pty2': 2, 
'_MyClass__pty3': 3, 
'func1': <function MyClass.func1 at 0x7f6898431378>, 
'func2': <function MyClass.func2 at 0x7f6898431400>, 
'_MyClass__func3': <function MyClass.__func3 at 0x7f6898431488>, 
'__len__': <function MyClass.__len__ at 0x7f6898431510>, 
'__dict__': <attribute '__dict__' of 'MyClass' objects>, 
'__weakref__': <attribute '__weakref__' of 'MyClass' objects>,
 '__doc__': None
 }
"""
View Code

 

 

魔術屬性

class Man():
    pass

class Woman():
    pass

class Sasuke(Man,Woman):
    """
描述: 佐助這個的天生屬性,技能
成員屬性:  __eye skin
成員方法: skylight __moonread
    """
    __eye = "血輪眼->萬花筒->輪迴眼"
    
    skin = "白色"
    
    def skylight(self , myfunc):
        print("使用天照,一團黑色的火焰 ... 恐怖如斯")
        res = myfunc.__name__
        print(res , type(res) )
        
    def __moonread(self):
        print("使用月讀,讓敵人拉入到幻術空間,被施法者掌握")

obj = Sasuke()
# __dict__ 獲取對象或類的內部成員結構
dic = Sasuke.__dict__
dic = obj.__dict__
print(dic)

# __doc__  獲取對象或類的內部文檔
print(Sasuke.__doc__)
print(obj.__doc__)

# __name__  獲取類名函數名
def func343434():
    print("佩恩出場時,使用一手地爆天星,技驚四座,點燃所有觀眾")

obj.skylight(func343434)

# __class__ 獲取當前對象所屬的類
print(obj.__class__)

# __bases__ 獲取一個類直接繼承的所有父類,返回元組
print(Sasuke.__bases__)
View Code

 


您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 在HarmonyOS中webview載入網頁的時候,需要有進度條,或者載入動畫進行用戶感知的交互,這樣可以優化用戶體驗,因此今天寫一篇載入動畫(效果如下)用於同學們進行學習,怎麼實現?首先我們需要學習“CommonDialog”“ WebView”“動畫開髮指導”三個知識儲備 我們分為“準備階段”, ...
  • 近日,HMS Core機器學習服務(ML Kit)文本翻譯功能在6.4.0版本更新中增加了10種小語種語言類型,分別是馬其他語、馬其頓、冰島、烏爾都語、波斯尼亞語、烏克蘭語、加泰羅尼亞語、斯洛維尼亞語、孟加拉語、南非荷蘭語。歡迎有相關出海App需求的開發者們訪問官網進一步瞭解,同時跟隨小編一起看看文 ...
  • 提到腳手架,大家想到的可能就是各種 xxx-cli,本文介紹的是另一種方式:以 vscode 插件的形式實現,提供 web 可視化操作,如下圖: 下麵介紹如何安裝使用,以及實現原理。 安裝使用 vscode 安裝 lowcode 插件,此插件是一個效率工具,腳手架只是其中一個功能,更多功能可以查看文 ...
  • 一、display:none; display翻譯成中文是顯示、展覽的意思;將display的屬性改為none可以實現元素的隱藏,元素和盒子模型也不生成,被隱藏的元素不占位置,看不見摸不著,它會導致瀏覽器的重排和重繪。 二、visibility:hidden; visibility翻譯成中文是能見、 ...
  • defer和async產生的原因 HTML 網頁中,瀏覽器通過<script>標簽載入 JavaScript 腳本。 <!-- 頁面內嵌的腳本 --> <script type="application/javascript"> // module code </script> <!-- 外部腳本 ...
  • 框架看起來就像是宗教(或者說是政治):每一個框架都假裝自己為開發者提供瞭解決方案,但每一個又都不一樣。它們每一個都聲稱可以為應用程式提供最好的前景,但關於哪一個真正名副其實的爭論又不絕於耳。每一個框架都要求你遵循特定的規則,它們之間可能有相似之處,但要從一個框架轉換到另一個框架總是很難。所以沒有什麼... ...
  • 屬性的簡潔表示法 ES6 允許在大括弧裡面直接寫入變數和函數,作為對象的屬性和方法。這樣的書寫更加簡潔。 const foo = 'bar'; const baz = { foo }; console.log(baz); // { foo: 'bar' } function f(name, age) ...
  • 一、冒泡排序 原理:相鄰兩元素之間兩兩比較,比較出大值進行賦值互換,再依次與相鄰的元素比較,層層遞進。#互換元素位置,相互賦值。 時間複雜度:最好O(n),最差O(n^2) 1、比較相鄰的兩個元素,如果前一個比後一個大,則交換位置。2、比較完第一輪的時候,最後一個元素是最大的元素。3、這時候最後一個 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...