Python 中的魔法方法是以雙下劃線開始和結束的特殊方法。它們也被稱為鄧德方法。魔法方法并不意味著由您直接調用,而是在某個動作上從類內部進行調用。例如,當您使用+運算符將兩個數字相加時,在內部將調用__add__()
方法。
Python 中的內置類定義了許多神奇的方法。使用dir()
函數查看一個類繼承的魔法方法數量。 例如,下面列出了在int
類中定義的所有屬性和方法。
>>> dir(int)
['__abs__', '__add__', '__and__', '__bool__', '__ceil__', '__class__', '__delattr__', '__dir__', '__divmod__', '__doc__', '__eq__', '__float__', '__floor__', '__floordiv__', '__format__', '__ge__', '__getattribute__', '__getnewargs__', '__gt__', '__hash__', '__index__', '__init__', '__init_subclass__', '__int__', '__invert__', '__le__', '__lshift__', '__lt__', '__mod__', '__mul__', '__ne__', '__neg__', '__new__', '__or__', '__pos__', '__pow__', '__radd__', '__rand__', '__rdivmod__', '__reduce__', '__reduce_ex__', '__repr__', '__rfloordiv__', '__rlshift__', '__rmod__', '__rmul__', '__ror__', '__round__', '__rpow__', '__rrshift__', '__rshift__', '__rsub__', '__rtruediv__', '__rxor__', '__setattr__', '__sizeof__', '__str__', '__sub__', '__subclasshook__', '__truediv__', '__trunc__', '__xor__', 'bit_length', 'conjugate', 'denominator', 'from_bytes', 'imag', 'numerator', 'real', 'to_bytes']
正如您在上面看到的,int 類包含了各種由雙下劃線包圍的神奇方法。例如,__add__
方法是一種神奇的方法,當我們使用+運算符將兩個數字相加時,它就會被調用。 考慮以下示例。 T3】
>>> num=10
>>> num + 5
15
>>> num.__add__(5)
15
可以看到,當你做num+10
時,+運算符調用__add__(10)
方法。 也可以直接打num.__add__(5)
會給出同樣的結果。 然而,如前所述,魔法方法并不意味著被直接調用,而是在內部,通過一些其他的方法或動作。
在 Python 中,魔術方法最常用于定義預定義運算符的重載行為。例如,默認情況下,算術運算符對數字操作數進行運算。這意味著數值對象必須與+、-、*、/等運算符一起使用。+運算符也被定義為字符串、列表和元組類中的串聯運算符。我們可以說+運算符是重載的。
為了使重載行為在您自己的自定義類中可用,應該重寫相應的 magic 方法。例如,為了將+運算符用于用戶定義類的對象,它應該包括__add__()
方法。
讓我們看看如何實現和使用一些重要的魔術方法。
new()方法
Java 和 C# 等語言使用新的運算符來創建類的新實例。在 Python 中,__new__()
魔法方法在__init__()
方法之前被隱式調用。__new__()
方法返回一個新的對象,然后由__init__()
初始化。
Example: new()
class Employee:
def __new__(cls):
print ("__new__ magic method is called")
inst = object.__new__(cls)
return inst
def __init__(self):
print ("__init__ magic method is called")
self.name='Satya'
當您創建Employee
類的實例時,上面的示例將產生以下輸出。
>>> emp = Employee()
__new__ magic method is called
__init__ magic method is called
因此,在__init__()
方法之前調用__new__()
方法。
str()方法
另一個有用的魔法方法是__str__()
。它被重寫以返回任何用戶定義類的可打印字符串表示形式。 我們已經看到str()
內置函數從對象參數返回一個字符串。例如,str(12)
返回‘12’。當被調用時,它調用 int 類中的__str__()
方法。
>>> num=12
>>> str(num)
'12'
>>> #This is equivalent to
>>> int.__str__(num)
'12'
現在讓我們重寫 Employee 類中的__str__()
方法,以返回其對象的字符串表示。
Example: str()
class Employee:
def __init__(self):
self.name='Swati'
self.salary=10000
def __str__(self):
return 'name='+self.name+' salary=$'+str(self.salary)
查看str()
函數如何在內部調用員工類中定義的__str__()
方法。這就是為什么它被稱為神奇的方法!
>>> e1=Employee()
>>> print(e1)
name=Swati salary=$10000
add()方法
在下面的示例中,一個名為 distance 的類定義了兩個實例屬性- ft 和 inch。這兩個距離對象的添加需要使用重載+運算符來執行。
為了實現這一點,神奇的方法__add__()
被覆蓋,它執行兩個對象的英尺和英寸屬性的添加。 方法返回對象的字符串表示。
Example: Override add()
class distance:
def __init__(self, x=None,y=None):
self.ft=x
self.inch=y
def __add__(self,x):
temp=distance()
temp.ft=self.ft+x.ft
temp.inch=self.inch+x.inch
if temp.inch>=12:
temp.ft+=1
temp.inch-=12
return temp
def __str__(self):
return 'ft:'+str(self.ft)+' in: '+str(self.inch)
運行上面的 Python 腳本來驗證+運算符的重載操作。
>>> d1=distance(3,10)
>>> d2=distance(4,4)
>>> print("d1= {} d2={}".format(d1, d2))
d1= ft:3 in: 10 d2=ft:4 in: 4
>>> d3=d1+d2
>>> print(d3)
ft:8 in: 2
ge()方法
在距離類中增加以下方法來重載>=
運算符。
Example: ge()
class distance:
def __init__(self, x=None,y=None):
self.ft=x
self.inch=y
def __ge__(self, x):
val1=self.ft*12+self.inch
val2=x.ft*12+x.inch
if val1>=val2:
return True
else:
return False
當使用>=
運算符并返回真或假時,調用該方法。相應地,可以顯示適當的信息
>>> d1=distance(2,1)
>>> d2=distance(4,10)
>>> d1>=d2
False
重要的魔術方法
下表列出了 Python 3 中的重要魔術方法。
初始化和構造 | 描述 |
---|---|
新 (cls,其他) | 在對象的實例化中被調用。 |
init(自身,其他) | 被 new 方法調用。 |
del(自我) | 析構函數方法。 |
一元運算符和函數 | 描述 |
---|---|
pos(自我) | 被要求一元正,例如+someobject。 |
neg(自我) | 為一元負數被調用,例如-someobject。 |
abs(自我) | 被內置的 abs()函數調用。 |
_ 反轉 _(自) | 使用~運算符進行反演。 |
_ 回合 _(自身,n) | 被內置 round()函數調用。 |
_ 樓層 _(自) | 被內置的 math.floor()函數調用。 |
ceil(自我) | 被內置的 math.ceil()函數調用。 |
trunc(自助) | 被內置的 math.trunc()函數調用。 |
擴充賦值 | 描述 |
---|---|
iadd(自身,其他) | 通過賦值來調用加法,例如 a +=b。 |
isub(自身,其他) | 在帶賦值的減法運算中被調用,例如 a -=b。 |
imul(自身、其他) | 被要求進行乘法運算,例如 a *=b。 |
ifloordiv(自身,其他) | 通過賦值調用整數除法,例如 a //=b。 |
idiv(自身,其他) | 被叫去分配任務,例如 a /=b。 |
itruediv(自身,其他) | 被叫去真正的部門分配任務 |
imod(自我,其他) | 通過賦值進行模調用,例如 a%=b。 |
ipow(自身、其他) | 在有賦值的指數上被調用,例如 a **=b。 |
ilshift(自身,其他) | 通過賦值(如 a<<=b)在按位左移時被調用。 |
irshift(自身,其他) | 通過賦值進行右位移位調用,例如 a >>=b。 |
_ 和 _(自身,其他) | 通過賦值按位“與”調用,例如 a&=b。 |
ior(自我,其他) | 通過賦值按位“或”調用,例如 a|=b。 |
ixor(自身、其他) | 通過賦值進行按位異或調用,例如^=b. |
類型轉換魔術方法 | 描述 |
---|---|
int(自我) | 由內置 int()方法調用,將類型轉換為 int。 |
float(自) | 由內置的浮點()方法調用,將類型轉換為浮點。 |
_ 復雜 _(自我) | 由內置的 complex()方法調用,將類型轉換為復雜類型。 |
_ 10 月 _ 日(自我) | 由內置的 int oct()方法調用,將類型轉換為八進制。 |
hex(自) | 由內置的 int hex()方法調用,將類型轉換為十六進制。 |
_ 索引 _(自我) | 當對象在切片表達式中使用時,在類型轉換為 int 時被調用。 |
trunc(自助) | 從 math.trunc()方法調用。 |
弦樂魔術方法 | 描述 |
---|---|
str(自我) | 方法調用以返回類型的字符串表示形式。 |
repr(自我) | 由內置的 int repr()方法調用以返回類型的機器可讀表示形式。 |
unicode(自我) | 由內置的 unicode()方法調用以返回類型的 unicode 字符串。 |
format(self,formatstr) | 由內置的 string.format()方法調用以返回新的字符串樣式。 |
hash(自我) | 由內置哈希()方法調用以返回一個整數。 |
_ 非零 _(自身) | 由內置 bool()方法調用以返回真或假。 |
dir(自助) | 由內置的 dir()方法調用以返回類的屬性列表。 |
sizeof(自我) | 由內置的 sys.getsizeof()方法調用以返回對象的大小。 |
屬性魔法方法 | 描述 |
---|---|
getattr(自我,姓名) | 當訪問不存在的類的屬性時調用。 |
setattr(自身、名稱、值) | 為類的屬性賦值時調用。 |
delattr(自我,姓名) | 在刪除類的屬性時調用。 |
運算符魔術方法 | 描述 |
---|---|
_ 添加 _(自身、其他) | 使用+運算符在添加操作時被調用 |
sub(自身、其他) | 使用-運算符在減法運算時被調用。 |
mul(自身、其他) | 使用*運算符調用乘法運算。 |
floordiv(自身、其他) | 使用//運算符調用樓層劃分操作。 |
truediv(自我,其他) | 使用/運算符調用除法運算。 |
mod(自身、其他) | 使用%運算符進行模運算時調用。 |
_ 冪 _(自身,其他[,模]) | 使用**運算符計算功率時被調用。 |
lt(自我,其他) | 使用 |
le(自我,其他) | 使用< =運算符進行比較時調用。 |
eq(自我,他人) | 使用==運算符進行比較時調用。 |
ne(自身,其他) | 使用進行比較時調用!=運算符。 |
ge(自身,其他) | 使用> =運算符進行比較時調用。 |
因此,您可以使用適當的魔法方法在自定義類中添加各種功能。
Further Reading ** https://rszalski . github . io/magic cmmethod*****