2010-07-06 77 views
5

我希望能夠讓我的類的運算符以我定義的方式與常規類型進行交互。比方說,例如,我有:Python:運算符重載特定類型

class Mynum(object): 
    def __init__(self, x): 
    self.x = x 
    def __add__(self, other): 
    return self.x + other.x 

a = Mynum(1) 
b = Mynum(2) 

print a+b 

這只是正常的,但現在,如果我嘗試做:

print a+2 

我得到,因爲一個int錯誤沒有一個成員名爲x 。如何在課堂上定義Mynum + int?這聽起來像是裝飾者或元類的工作,但我對他們的用法非常陌生。 This question似乎相似,但不完全相同。

+0

檢查「x」屬性的類型或「其他」或存在。 – SilentGhost 2010-07-06 17:32:15

+0

不要忘了: '__radd__' ='__add__' (即使它不能解決您的問題) – jcao219 2010-07-06 17:35:51

回答

11
def __add__(self, other): 
    if isinstance(other, self.__class__): 
     return self.x + other.x 
    elif isinstance(other, int): 
     return self.x + other 
    else: 
     raise TypeError("unsupported operand type(s) for +: '{}' and '{}'").format(self.__class__, type(other)) 
+0

謝謝,我從來沒有見過'isinstance'之前。這是否被認爲是做到這一點的正確方法,還是應該使用unutbu建議的try/except塊? – Hooked 2010-07-06 17:53:12

+0

當沒有發生異常時,'try ... except'子句很快,否則就會變慢。因此,如果添加兩個類的實例是重載添加的最常見用法,則可以使用它。否則,'insinstance'方法很好。 – EOL 2010-07-06 18:54:34

+0

你不應該返回'NotImplemented'而不是自己提升和異常嗎? – jpcgt 2016-04-07 14:00:06

4
class Mynum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     try: 
      return self.x + other.x 
     except AttributeError: 
      return self.x + other 
    __radd__=__add__ 

a = Mynum(1) 
b = Mynum(2) 

print(a+b) 
# 3 
print(a+2) 
# 3 
print(2+a) 
# 3 
2

爲什麼要使用額外的開關和/或異常處理?使用以下將是一種更簡單的方法:

class MyNum(object): 
    def __init__(self, x): 
     self.x = x 
    def __add__(self, other): 
     return other + self.x 
    __radd__ = __add__ 
x = MyNum(5) 
y = MyNum(6) 
print x + 2 
7 
print 2 + x 
7 
print x + y 
11 
print y + x 
11