2014-03-05 45 views
1

今天,我正在讀一本關於python的書,並且我知道有一些神奇的方法,例如__add____mul__我如何重寫魔術方法?

但是,在這本書中,沒有解釋如何使用它們。

所以,我試圖找出自己。但是,我無法弄清楚如何重寫魔術方法。 這是我試過的代碼。

>>> class Num(int): 
...  def __init__(self, number): 
...    self.number = number 
...  def __add__(self, other): 
...    self.number += other*100 
...    return self.number 
... 
>>> num = Num(10) 
>>> num.number + 10 
20 

任何人都可以請幫我理解這些神奇的方法是如何工作的嗎?

+6

如果你想'__add__'生效,你需要添加到'num',而不是'num.number'。試試'num + 10'。 – BrenBarn

+0

哦,謝謝!有用!現在,我需要考慮如何利用這些神奇的方法。 – crzyonez777

+3

請注意'__add__'不應該修改它操作的對象,而是返回一個新對象。你所做的基本上是'__iadd__'。通常情況下,可以這樣做:def __add __(self,other):return Num(self.number + other * 100)'和'def __iadd __(self,other):self。數字+ =其他* 100;返回自我' – glglgl

回答

2
class Num: 
    def __init__(self, number): 
     self.number = number 
    def __add__(self, other): 
     self.number += other*100 

>> num = Num(10) 
>> num.number 
10 
>> num + 10 # note that you are adding to num, not to num.number 
>> num.number 
1010 

這就是__add__重寫的原理。與return版本:

class Num: 
    def __init__(self, number): 
     self.number = number 
    def __add__(self, other): 
     return self.number + other*100 

>> num = Num(10) 
>> num.number 
10 
>> num + 10 # again adding to num 
1010 
>> num.number 
10 

當Python看到

x + y 
x += y 
x * y 
x *= y 
etc 

它,它轉化爲

x.__add__(y) 
x.__iadd__(y) 
x.__mul__(y) 
x.__imul__(y) 
etc 
3
In [12]: class Num(int): 
    ...:  def __init__(self, number): 
    ...:    self.number = number 
    ...:  def __add__(self, other): 
    ...:    #self.number += other*100 #why do you want to do other*100? 
    ...:    return Num(self.number+ 
    ...:       Num(other).number) #wrap "other" with "Num" 
                #in case "other" is an "int" 

In [13]: num = Num(10) 
    ...: print num+10 
20 

其實,你並不需要重寫__add__如果您Numint一個子類。只需撥打super__init__就足夠了:

In [19]: class Num(int): 
    ...:  def __init__(self, *args): 
    ...:   super(Num, self).__init__(args) 

In [20]: Num(10) 
Out[20]: 10 

In [21]: Num(10)+10 
Out[21]: 20 

而這樣一來,需要像self.number沒有其他屬性。

+0

@eryksun請問在這種情況下稱爲超級的缺點是什麼? – zhangxaochen

+0

@eryksun如果沒有其他實例屬性,那麼這是真的;) – zhangxaochen

1

你是想重寫您類的方法,而不是一所以基本上具體屬性。

在您的實現,num.number + 10觸發您__add__方法,而是你所操作的變量的方法 - 在你的情況下,int

num.number.__add__ 

這就是爲什麼你看到的20輸出 - 它使用默認__add__ 10 + 10 = 20

如果你想用你類的方法,你會做這樣的:

num = Num(10) 
num + 10 

現在您正在訪問num.__add__方法。