亚洲乱码中文字幕综合,中国熟女仑乱hd,亚洲精品乱拍国产一区二区三区,一本大道卡一卡二卡三乱码全集资源,又粗又黄又硬又爽的免费视频

從入門到精通的Python魔術(shù)方法(Magic Methods)完全指南

 更新時(shí)間:2025年07月17日 08:38:41   作者:盛夏綻放  
這篇文章主要詳細(xì)介紹了Python中特殊的魔術(shù)方法,用于實(shí)現(xiàn)各種內(nèi)置操作,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下

本文全面介紹了Python中特殊的魔術(shù)方法,這些以雙下劃線開頭和結(jié)尾的方法(如__init__)為類提供了"魔法"般的行為。主要內(nèi)容包括:

基礎(chǔ)知識(shí):魔術(shù)方法由Python自動(dòng)調(diào)用,用于實(shí)現(xiàn)各種內(nèi)置操作,如對(duì)象初始化(init)、字符串表示(str, repr)等。

核心分類:

  • 對(duì)象生命周期方法(new, del)
  • 比較運(yùn)算符(eq, __lt__等)
  • 算術(shù)運(yùn)算(add, __mul__等)
  • 容器模擬(len, __getitem__等)

實(shí)際應(yīng)用:通過(guò)豐富的代碼示例展示了如何利用魔術(shù)方法實(shí)現(xiàn)自定義類的高級(jí)行為,如向量運(yùn)算、購(gòu)物車容器等。

魔術(shù)方法使Python的面向?qū)ο缶幊谈訌?qiáng)大和靈活,是構(gòu)建專業(yè)級(jí)Python類的關(guān)鍵工具。

魔術(shù)方法(Magic Methods)是Python面向?qū)ο缶幊讨械奶厥夥椒?,它們賦予類"魔法"般的行為。本文將全面解析Python中的魔術(shù)方法,通過(guò)豐富的示例和實(shí)際應(yīng)用場(chǎng)景,帶你深入理解這一重要概念。

一、魔術(shù)方法基礎(chǔ)

1. 什么是魔術(shù)方法

魔術(shù)方法是以雙下劃線開頭和結(jié)尾的特殊方法(如__init__),Python會(huì)在特定時(shí)機(jī)自動(dòng)調(diào)用它們。它們不是用來(lái)直接調(diào)用的,而是讓類能夠支持Python的各種內(nèi)置操作。

class MyClass:
    def __init__(self, value):
        self.value = value
    
    def __str__(self):
        return f"MyClass with value: {self.value}"

obj = MyClass(42)
print(obj)  # 自動(dòng)調(diào)用__str__: "MyClass with value: 42"

2. 魔術(shù)方法的特點(diǎn)

  • 命名規(guī)則:雙下劃線開頭和結(jié)尾,如__method__
  • 自動(dòng)調(diào)用:由Python解釋器在特定情況下調(diào)用
  • 豐富功能:實(shí)現(xiàn)運(yùn)算符重載、對(duì)象生命周期控制等
  • 性能優(yōu)化:比普通方法調(diào)用更快(直接由解釋器處理)

二、常用魔術(shù)方法分類詳解

1. 對(duì)象創(chuàng)建與初始化

方法調(diào)用時(shí)機(jī)典型用途
__new__創(chuàng)建實(shí)例時(shí)控制實(shí)例創(chuàng)建過(guò)程(單例模式等)
__init__初始化實(shí)例時(shí)設(shè)置初始屬性
__del__對(duì)象銷毀時(shí)清理資源
class Resource:
    def __new__(cls, *args, **kwargs):
        print("__new__ called - creating instance")
        instance = super().__new__(cls)
        return instance
    
    def __init__(self, name):
        print("__init__ called - initializing")
        self.name = name
    
    def __del__(self):
        print(f"__del__ called - cleaning up {self.name}")

res = Resource("File")  # 輸出: __new__ called → __init__ called
del res                 # 輸出: __del__ called

2. 對(duì)象表示與字符串轉(zhuǎn)換

方法調(diào)用時(shí)機(jī)區(qū)別
__str__str(obj), print(obj)用戶友好的字符串表示
__repr__repr(obj), 交互式環(huán)境明確的、可eval的表示
__format__format(obj), f-string自定義格式化輸出
class Point:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __str__(self):
        return f"({self.x}, {self.y})"
    
    def __repr__(self):
        return f"Point({self.x}, {self.y})"
    
    def __format__(self, format_spec):
        if format_spec == 'r':
            return f"{self.x}×{self.y}"
        return str(self)

p = Point(3, 4)
print(str(p))      # (3, 4)
print(repr(p))     # Point(3, 4)
print(f"{p}")      # (3, 4)
print(f"{p:r}")    # 3×4

3. 比較運(yùn)算符重載

方法對(duì)應(yīng)運(yùn)算符
__lt__<
__le__<=
__eq__==
__ne__!=
__gt__>
__ge__>=
class Student:
    def __init__(self, name, score):
        self.name = name
        self.score = score
    
    def __eq__(self, other):
        return self.score == other.score
    
    def __lt__(self, other):
        return self.score < other.score
    
    def __le__(self, other):
        return self.score <= other.score

alice = Student("Alice", 85)
bob = Student("Bob", 90)
print(alice < bob)   # True
print(alice == bob)  # False

4. 算術(shù)運(yùn)算符重載

方法對(duì)應(yīng)運(yùn)算符反向方法
__add__+__radd__
__sub__-__rsub__
__mul__*__rmul__
__truediv__/__rtruediv__
__floordiv__//__rfloordiv__
__mod__%__rmod__
__pow__**__rpow__
class Vector:
    def __init__(self, x, y):
        self.x = x
        self.y = y
    
    def __add__(self, other):
        return Vector(self.x + other.x, self.y + other.y)
    
    def __mul__(self, scalar):
        if isinstance(scalar, (int, float)):
            return Vector(self.x * scalar, self.y * scalar)
        return NotImplemented
    
    def __rmul__(self, scalar):
        return self.__mul__(scalar)
    
    def __str__(self):
        return f"Vector({self.x}, {self.y})"

v1 = Vector(2, 3)
v2 = Vector(5, 7)
print(v1 + v2)  # Vector(7, 10)
print(v1 * 3)   # Vector(6, 9)
print(2 * v1)   # Vector(4, 6) (調(diào)用__rmul__)

5. 容器類型模擬

方法用途
__len__len(obj)
__getitem__obj[key]
__setitem__obj[key] = value
__delitem__del obj[key]
__contains__item in obj
__iter__迭代對(duì)象時(shí)
class ShoppingCart:
    def __init__(self):
        self.items = []
    
    def __len__(self):
        return len(self.items)
    
    def __getitem__(self, index):
        return self.items[index]
    
    def __setitem__(self, index, value):
        self.items[index] = value
    
    def __delitem__(self, index):
        del self.items[index]
    
    def __contains__(self, item):
        return item in self.items
    
    def __iter__(self):
        return iter(self.items)
    
    def add(self, item):
        self.items.append(item)

cart = ShoppingCart()
cart.add("蘋果")
cart.add("香蕉")
cart.add("橙子")

print(len(cart))        # 3
print(cart[1])          # 香蕉
print("蘋果" in cart)   # True

for item in cart:       # 迭代
    print(item)

6. 上下文管理器

方法調(diào)用時(shí)機(jī)
__enter__進(jìn)入with塊時(shí)
__exit__退出with塊時(shí)
class Timer:
    def __enter__(self):
        import time
        self.start = time.time()
        return self
    
    def __exit__(self, exc_type, exc_val, exc_tb):
        import time
        self.end = time.time()
        print(f"耗時(shí): {self.end - self.start:.2f}秒")
    
    def elapsed(self):
        return self.end - self.start

with Timer() as t:
    # 執(zhí)行一些操作
    sum(range(1000000))

# 自動(dòng)輸出: 耗時(shí): x.xx秒

7. 可調(diào)用對(duì)象

方法調(diào)用時(shí)機(jī)
__call__obj()形式調(diào)用時(shí)
class Adder:
    def __init__(self, n):
        self.n = n
    
    def __call__(self, x):
        return self.n + x

add5 = Adder(5)
print(add5(3))  # 8 (實(shí)例像函數(shù)一樣調(diào)用)

三、高級(jí)魔術(shù)方法

1. 屬性訪問(wèn)控制

方法調(diào)用時(shí)機(jī)
__getattr__訪問(wèn)不存在的屬性時(shí)
__getattribute__訪問(wèn)任何屬性時(shí)
__setattr__設(shè)置屬性時(shí)
__delattr__刪除屬性時(shí)
class AttributeLogger:
    def __init__(self):
        self.data = {}
    
    def __getattr__(self, name):
        print(f"訪問(wèn)不存在的屬性: {name}")
        return None
    
    def __setattr__(self, name, value):
        print(f"設(shè)置屬性: {name} = {value}")
        super().__setattr__(name, value)
    
    def __delattr__(self, name):
        print(f"刪除屬性: {name}")
        super().__delattr__(name)

obj = AttributeLogger()
obj.x = 10      # 設(shè)置屬性: x = 10
print(obj.x)    # 10
print(obj.y)    # 訪問(wèn)不存在的屬性: y → None
del obj.x       # 刪除屬性: x

2. 描述符協(xié)議

方法調(diào)用時(shí)機(jī)
__get__獲取描述符值時(shí)
__set__設(shè)置描述符值時(shí)
__delete__刪除描述符值時(shí)
class Celsius:
    def __get__(self, instance, owner):
        return instance._celsius
    
    def __set__(self, instance, value):
        if value < -273.15:
            raise ValueError("溫度不能低于絕對(duì)零度")
        instance._celsius = value

class Temperature:
    celsius = Celsius()  # 描述符
    
    def __init__(self, celsius):
        self.celsius = celsius  # 通過(guò)描述符賦值

temp = Temperature(25)
print(temp.celsius)  # 25
temp.celsius = 30    # 通過(guò)描述符修改
# temp.celsius = -300 # 報(bào)錯(cuò)

3. 數(shù)值類型轉(zhuǎn)換

方法調(diào)用時(shí)機(jī)
__int__int(obj)
__float__float(obj)
__bool__bool(obj)
__complex__complex(obj)
class Percentage:
    def __init__(self, value):
        self.value = value
    
    def __int__(self):
        return int(self.value)
    
    def __float__(self):
        return float(self.value / 100)
    
    def __bool__(self):
        return self.value != 0
    
    def __str__(self):
        return f"{self.value}%"

p = Percentage(75)
print(int(p))      # 75
print(float(p))    # 0.75
print(bool(p))     # True
print(bool(Percentage(0)))  # False

四、魔術(shù)方法最佳實(shí)踐

謹(jǐn)慎使用:只在確實(shí)需要時(shí)實(shí)現(xiàn)魔術(shù)方法

保持一致性

  • 實(shí)現(xiàn)__eq__時(shí)也應(yīng)實(shí)現(xiàn)__hash__
  • 實(shí)現(xiàn)比較運(yùn)算符時(shí)最好實(shí)現(xiàn)全套

性能考慮:魔術(shù)方法會(huì)被頻繁調(diào)用,應(yīng)保持高效

文檔說(shuō)明:明確記錄每個(gè)魔術(shù)方法的行為

避免過(guò)度使用:不是所有類都需要成為"全能選手"

五、綜合案例:自定義分?jǐn)?shù)類

class Fraction:
    """自定義分?jǐn)?shù)類,演示多種魔術(shù)方法"""
    
    def __init__(self, numerator, denominator=1):
        if denominator == 0:
            raise ValueError("分母不能為零")
        
        # 約分
        common = self.gcd(numerator, denominator)
        self.num = numerator // common
        self.den = denominator // common
    
    @staticmethod
    def gcd(a, b):
        """計(jì)算最大公約數(shù)"""
        while b:
            a, b = b, a % b
        return a
    
    def __add__(self, other):
        """重載+運(yùn)算符"""
        if isinstance(other, int):
            other = Fraction(other)
        new_num = self.num * other.den + other.num * self.den
        new_den = self.den * other.den
        return Fraction(new_num, new_den)
    
    __radd__ = __add__  # 反向加法
    
    def __sub__(self, other):
        """重載-運(yùn)算符"""
        return self.__add__(-other)
    
    def __neg__(self):
        """重載負(fù)號(hào)"""
        return Fraction(-self.num, self.den)
    
    def __mul__(self, other):
        """重載*運(yùn)算符"""
        if isinstance(other, int):
            other = Fraction(other)
        return Fraction(self.num * other.num, self.den * other.den)
    
    __rmul__ = __mul__  # 反向乘法
    
    def __truediv__(self, other):
        """重載/運(yùn)算符"""
        if isinstance(other, int):
            other = Fraction(other)
        return Fraction(self.num * other.den, self.den * other.num)
    
    def __eq__(self, other):
        """重載==運(yùn)算符"""
        if isinstance(other, int):
            other = Fraction(other)
        return self.num == other.num and self.den == other.den
    
    def __lt__(self, other):
        """重載<運(yùn)算符"""
        return self.num * other.den < other.num * self.den
    
    def __le__(self, other):
        """重載<=運(yùn)算符"""
        return self.__lt__(other) or self.__eq__(other)
    
    def __str__(self):
        """字符串表示"""
        if self.den == 1:
            return str(self.num)
        return f"{self.num}/{self.den}"
    
    def __repr__(self):
        """解釋器表示"""
        return f"Fraction({self.num}, {self.den})"
    
    def __float__(self):
        """轉(zhuǎn)換為浮點(diǎn)數(shù)"""
        return self.num / self.den

# 使用示例
f1 = Fraction(3, 4)
f2 = Fraction(2, 5)

print(f1 + f2)    # 23/20
print(f1 - f2)    # 7/20
print(f1 * f2)    # 3/10
print(f1 / f2)    # 15/8
print(f1 == Fraction(6, 8))  # True
print(f1 < f2)    # False
print(float(f1))  # 0.75
print(2 + f1)     # 11/4 (調(diào)用__radd__)

通過(guò)這個(gè)完整的分?jǐn)?shù)類實(shí)現(xiàn),我們綜合運(yùn)用了多種魔術(shù)方法,使自定義類能夠像內(nèi)置類型一樣自然地參與各種運(yùn)算和操作。

魔術(shù)方法是Python強(qiáng)大而靈活的特性,合理使用它們可以讓你的類更加Pythonic,與Python語(yǔ)言的其他特性無(wú)縫集成。記住,能力越大責(zé)任越大,魔術(shù)方法應(yīng)該用來(lái)增強(qiáng)代碼的清晰度和可用性,而不是制造"魔法"般的復(fù)雜性。

以上就是從入門到精通的Python魔術(shù)方法(Magic Methods)完全指南的詳細(xì)內(nèi)容,更多關(guān)于Python魔術(shù)方法的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • 用Python給二維碼圖片添加提示文字

    用Python給二維碼圖片添加提示文字

    今天教各位小伙伴怎么用Python給二維碼圖片添加提示文字,文中有非常詳細(xì)的代碼示例,對(duì)正在學(xué)習(xí)python的小伙伴很有幫助,需要的朋友可以參考下
    2021-05-05
  • python使用numpy按一定格式讀取bin文件的實(shí)現(xiàn)

    python使用numpy按一定格式讀取bin文件的實(shí)現(xiàn)

    這篇文章主要介紹了python使用numpy按一定格式讀取bin文件的實(shí)現(xiàn)方式,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2023-05-05
  • python中類變量與成員變量的使用注意點(diǎn)總結(jié)

    python中類變量與成員變量的使用注意點(diǎn)總結(jié)

    python 的類中主要會(huì)使用的兩種變量:類變量與成員變量。類變量是類所有實(shí)例化對(duì)象共有的,而成員變量是每個(gè)實(shí)例化對(duì)象自身特有的。下面這篇文章主要給大家介紹了在python中類變量與成員變量的一些使用注意點(diǎn),需要的朋友可以參考借鑒,下面來(lái)一起看看吧。
    2017-04-04
  • pandas dataframe rolling移動(dòng)計(jì)算方式

    pandas dataframe rolling移動(dòng)計(jì)算方式

    在Pandas中,rolling()方法用于執(zhí)行移動(dòng)窗口計(jì)算,常用于時(shí)間序列數(shù)據(jù)分析,例如,計(jì)算某商品的7天或1個(gè)月銷售總量,可以通過(guò)rolling()輕松實(shí)現(xiàn),該方法的關(guān)鍵參數(shù)包括window(窗口大小),min_periods(最小計(jì)算周期)
    2024-09-09
  • Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊用法分析

    Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊用法

    這篇文章主要介紹了Python3.5內(nèi)置模塊之shelve模塊、xml模塊、configparser模塊、hashlib、hmac模塊,結(jié)合實(shí)例形式較為詳細(xì)的分析了shelve、xml、configparser、hashlib、hmac等模塊的功能及使用方法,需要的朋友可以參考下
    2019-04-04
  • Python快速生成隨機(jī)密碼超簡(jiǎn)單實(shí)現(xiàn)

    Python快速生成隨機(jī)密碼超簡(jiǎn)單實(shí)現(xiàn)

    這篇文章主要介紹了Python快速生成隨機(jī)密碼,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來(lái)一起學(xué)習(xí)學(xué)習(xí)吧
    2022-08-08
  • Python中rapidjson參數(shù)校驗(yàn)實(shí)現(xiàn)

    Python中rapidjson參數(shù)校驗(yàn)實(shí)現(xiàn)

    通常需要對(duì)前端傳遞過(guò)來(lái)的參數(shù)進(jìn)行校驗(yàn),校驗(yàn)的方式有多種,本文主要介紹了Python中rapidjson參數(shù)校驗(yàn)實(shí)現(xiàn),具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2021-07-07
  • Python3.6通過(guò)自帶的urllib通過(guò)get或post方法請(qǐng)求url的實(shí)例

    Python3.6通過(guò)自帶的urllib通過(guò)get或post方法請(qǐng)求url的實(shí)例

    下面小編就為大家分享一篇Python3.6通過(guò)自帶的urllib通過(guò)get或post方法請(qǐng)求url的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧
    2018-05-05
  • 使用Python和jieba庫(kù)生成中文詞云的示例代碼

    使用Python和jieba庫(kù)生成中文詞云的示例代碼

    在文本分析和數(shù)據(jù)可視化的領(lǐng)域中,詞云是一種展示文本數(shù)據(jù)中關(guān)鍵詞頻率的直觀方式,Python作為一種強(qiáng)大的編程語(yǔ)言,提供了多種庫(kù)來(lái)幫助我們生成詞云,在本文中,我們將通過(guò)一個(gè)簡(jiǎn)單的示例,展示如何使用Python生成中文詞云,需要的朋友可以參考下
    2024-07-07
  • python實(shí)現(xiàn)用戶答題功能

    python實(shí)現(xiàn)用戶答題功能

    這篇文章主要為大家詳細(xì)介紹了python實(shí)現(xiàn)用戶答題功能,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下
    2018-01-01

最新評(píng)論