溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務(wù)條款》

Python的雙下方法怎么使用

發(fā)布時間:2022-07-22 09:38:52 來源:億速云 閱讀:102 作者:iii 欄目:編程語言

本文小編為大家詳細(xì)介紹“Python的雙下方法怎么使用”,內(nèi)容詳細(xì),步驟清晰,細(xì)節(jié)處理妥當(dāng),希望這篇“Python的雙下方法怎么使用”文章能幫助大家解決疑惑,下面跟著小編的思路慢慢深入,一起來學(xué)習(xí)新知識吧。

Python的雙下方法怎么使用

前言

大家在寫 Python 代碼的時候有沒有這樣的疑問。

為什么數(shù)學(xué)中的+號,在字符串運算中卻變成拼接功能,如'ab' + 'cd'結(jié)果為abcd;而*號變成了重復(fù)功能,如'ab' * 2結(jié)果為abab。

為什么某些對象print能輸出數(shù)據(jù),而print自定義的類對象卻輸出一堆看不懂的代碼<__main__.MyCls object at 0x105732250>

不是因為系統(tǒng)做了特殊定制,而是 Python 中有一類特殊的方法,在某些特定的場合會自動調(diào)用。如,在字符串類str中定義了__add__方法后,當(dāng)代碼遇到字符串相加'ab' + 'cd'時,就會自動調(diào)用__add__方法完成字符串拼接。

因為這類特殊方法的方法名都是以雙下劃線開始和結(jié)束,所以又被稱為雙下方法。

Python 中的雙下方法很多,今天我們對它做個詳解。

Python的雙下方法怎么使用

Python中的雙下方法

1. init方法

__init__的方法是很多人接觸的第一個雙下方法。

class A:
    def __init__(self, a):
        self.a = a

當(dāng)調(diào)用A()實例化對象的時候,__init__方法會被自動調(diào)用,完成對象的初始化。

2. 運算符的雙下方法

在類中定義運算符相關(guān)的雙下方法,可以直接在類對象上做加減乘除、比較等操作。

這里,定義一個尺子類Rule,它包含一個屬性r_len代表尺子的長度。

class Rule:
    def __init__(self, r_len):
        self.r_len = r_len

2.1 比較運算符

如果想按照尺子的長度對不同的尺子做比較,需要在Rule類中定義比較運算符。

class Rule:
    def __init__(self, r_len):
        self.r_len = r_len

    # < 運算符
    def __lt__(self, other):
        return self.r_len < other.r_len

    # <= 運算符
    def __le__(self, other):
        return self.r_len <= other.r_len

    # > 運算符
    def __gt__(self, other):
        return self.r_len > other.r_len

    # >= 運算符
    def __ge__(self, other):
        return self.r_len >= other.r_len

這里定義了<、<=>>=四個比較運算符,這樣就可以用下面的代碼比較Rule對象了。

rule1 = Rule(10)
rule2 = Rule(5)
print(rule1 > rule2)  # True
print(rule1 >= rule2)  # True
print(rule1 < rule2)  # False
print(rule1 <= rule2)  # False

當(dāng)用>比較rule1rule2的時候,rule1對象會自動調(diào)用__gt__方法,并將rule2對象傳給other參數(shù),完成比較。

下面是比較運算符的雙下方法

Python的雙下方法怎么使用

比較運算符雙下方法

2.2 算術(shù)運算符

可以支持類對象加減乘除。

def __add__(self, other):
    return Rule(self.r_len + other.r_len)

這里定義了__add__方法,對應(yīng)的是+運算符,他會把兩個尺子的長度相加,并生成新的尺子。

rule1 = Rule(10)
rule2 = Rule(5)
rule3 = rule1 + rule2

下面是算術(shù)運算符的雙下方法

Python的雙下方法怎么使用

2.3 反向算術(shù)運算符

它支持其他類型的變量與Rule類相加。以__radd__方法為例

def __radd__(self, other):
    return self.r_len + other
rule1 = Rule(10)
rule2 = 10 + rule1

程序執(zhí)行10 + rule1時,會嘗試調(diào)用int類的__add__int類類沒有定義與Rule類對象相加的方法,所以程序會調(diào)用+號右邊對象rule1__radd__方法,并把10傳給other參數(shù)。

所以這種運算符又叫右加運算符。它所支持的運算符與上面的算術(shù)運算符一樣,方法名前加r即可。

2.4 增量賦值運算符

增量賦值運算符是+=、-=、*=、/=等。

def __iadd__(self, other):
    self.r_len += other
    return self
rule1 = Rule(10)
rule1 += 5

除了__pmod__方法,其他的跟算數(shù)運算符一樣,方面名前都加i。

2.4 位運算符

這部分支持按二進制進行取反、移位和與或非等運算。由于Rule類不涉及位運算,所以我們換一個例子。

定義二進制字符串的類BinStr,包含bin_str屬性,表示二進制字符串。

class BinStr:
    def __init__(self, bin_str):
        self.bin_str = bin_str
x = BinStr('1010')  #創(chuàng)建二進制字符串對象
print(x.bin_str) # 1010

BinStr定義一個取反運算符~

# ~ 運算符
def __invert__(self):
    inverted_bin_str = ''.join(['1' if i == '0' else '0' for i in self.bin_str])
    return BinStr(inverted_bin_str)

__invert__方法中,遍歷bin_str字符串,將每位取反,并返回一個新的BinStr類對象。

x = BinStr('1011')

invert_x = ~x
print(invert_x.bin_str) # 0100

下面是位運算符的雙下方法

Python的雙下方法怎么使用

這部分也支持反向位運算符和增量賦值位運算符,規(guī)則跟算數(shù)運算符一樣,這里就不再贅述。

3.字符串表示

這部分涉及兩個雙下方法__repr____format__,在某些特殊場景,如print,會自動調(diào)用,將對象轉(zhuǎn)成字符串。

還是以BinStr為例,先寫__repr__方法。

def __repr__(self):
    decimal = int('0b'+self.bin_str, 2)
    return f'二進制字符串:{self.bin_str},對應(yīng)的十進制數(shù)字:{decimal}'
x = BinStr('1011')
print(x)
# 輸出:二進制字符串:1011,對應(yīng)的十進制數(shù)字:11

當(dāng)程序執(zhí)行print(x)時,會自動調(diào)用__repr__方法,獲取對象x對應(yīng)的字符串。

再寫__format__方法,它也是將對象格式化為字符串。

def __format__(self, format_spec):
    return format_spec % self.bin_str
print('{0:二進制字符串:%s}'.format(x))
# 輸出:二進制字符串:1011

當(dāng).format方法的前面字符串里包含0:時,就會自動調(diào)用__format__方法,并將字符串傳給format_spec參數(shù)。

4.數(shù)值轉(zhuǎn)換

調(diào)用int(obj)、float(obj)等方法,可以將對象轉(zhuǎn)成相對應(yīng)數(shù)據(jù)類型的數(shù)據(jù)。

def __int__(self):
    return int('0b'+self.bin_str, 2)
x = BinStr('1011')
print(int(x))

當(dāng)調(diào)用int(x)時,會自動調(diào)用__int__方法,將二進制字符串轉(zhuǎn)成十進制數(shù)字。

數(shù)值轉(zhuǎn)換除了上面的兩個外,還有__abs__、__bool__、__complex____hash__、__index____str__

__str____repr__一樣,在print時都會被自動調(diào)用,但__str__優(yōu)先級更高。

5.集合相關(guān)的雙下方法

這部分可以像集合那樣,定義對象長度、獲取某個位置元素、切片等方法。

__len____getitem__為例

def __len__(self):
    return len(self.bin_str)

def __getitem__(self, item):
    return self.bin_str[item]
x = BinStr('1011')

print(len(x))  # 4
print(x[0])  # 1
print(x[0:3])  # 101

len(x)會自動調(diào)用__len__返回對象的長度。

通過[]方式獲取對象的元素時,會自動調(diào)用__getitem__方法,并將切片對象傳給item參數(shù),即可以獲取單個元素,還可以獲取切片。

集合相關(guān)的雙下方法還包括__setitem__、__delitem____contains__

6.迭代相關(guān)的雙下方法

可以在對象上使用for-in遍歷。

def __iter__(self):
    self.cur_i = -1
    return self

def __next__(self):
    self.cur_i += 1
    if self.cur_i >= len(self.bin_str):
        raise StopIteration()  # 退出迭代
    return self.bin_str[self.cur_i]
x = BinStr('1011')
for i in x:
    print(i)

當(dāng)在x上使用for-in循環(huán)時,會先調(diào)用__iter__方法將游標(biāo)cur_i置為初始值-1,然后不斷調(diào)用__next__方法遍歷self.bin_str中的每一位。

這部分還有一個__reversed__方法用來反轉(zhuǎn)對象。

def __reversed__(self):
    return BinStr(''.join(list(reversed(self.bin_str))))
x = BinStr('1011')
reversed_x = reversed(x)
print(reversed_x)
# 輸出:二進制字符串:1101,對應(yīng)的十進制數(shù)字:13

7.類相關(guān)的雙下方法

做 web 開發(fā)的朋友,用類相關(guān)的雙下方法會更多一些。

7.1 實例的創(chuàng)建和銷毀

實例的創(chuàng)建是__new____init__方法,實例的銷毀是__del__方法。

__new__的調(diào)用早于__init__,它的作用是創(chuàng)建對象的實例(內(nèi)存開辟一段空間),而后才將該實例傳給__init__方法,完成實例的初始化。

由于__new__是類靜態(tài)方法,因此它可以控制對象的創(chuàng)建,從而實現(xiàn)單例模式。

__del__方法在實例銷毀時,被自動調(diào)用,可以用來做一些清理工作和資源釋放的工作。

7.2 屬性管理

類屬性的訪問和設(shè)置。包括__getattr__、__getattribute____setattr____delattr__方法。

__getattr____getattribute__的區(qū)別是,當(dāng)訪問類屬性時,無論屬性存不存在都會調(diào)用__getattribute__方法,只有當(dāng)屬性不存在時才會調(diào)用__getattr__方法。

7.3 屬性描述符

控制屬性的訪問,一般用于把屬性的取值控制在合理范圍內(nèi)。包括__get__、__set____delete__方法。

class XValidation:
    def __get__(self, instance, owner):
        return self.x

    def __set__(self, instance, value):
        if 0 <= value <= 100:
            self.x = value
        else:
            raise Exception('x不能小于0,不能大于100')

    def __delete__(self, instance):
        print('刪除屬性')


class MyCls:
    x = XValidation()

    def __init__(self, n):
        self.x = n

obj = MyCls(10)
obj.x = 101
print(obj.x) # 拋異常:Exception: x不能小于0,不能大于100

上述例子,通過類屬性描述符,可以將屬性x的取值控制在[0, 100]之前,防止不合法的取值。

讀到這里,這篇“Python的雙下方法怎么使用”文章已經(jīng)介紹完畢,想要掌握這篇文章的知識點還需要大家自己動手實踐使用過才能領(lǐng)會,如果想了解更多相關(guān)內(nèi)容的文章,歡迎關(guān)注億速云行業(yè)資訊頻道。

向AI問一下細(xì)節(jié)

免責(zé)聲明:本站發(fā)布的內(nèi)容(圖片、視頻和文字)以原創(chuàng)、轉(zhuǎn)載和分享為主,文章觀點不代表本網(wǎng)站立場,如果涉及侵權(quán)請聯(lián)系站長郵箱:is@yisu.com進行舉報,并提供相關(guān)證據(jù),一經(jīng)查實,將立刻刪除涉嫌侵權(quán)內(nèi)容。

AI