2010-07-06 94 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