Python

时间:2015-11-26 13:20:47

标签: python

例如,如果我想以下列方式对对象应用数学运算:

class A(object):
     def __init__(self, value):
         self.value = value

     def __repr__(self):
         return value

assert(A(1) + A(2) == 3)

我收到以下错误:TypeError: unsupported operand type(s) for +: 'A' and 'A'

是否可以将对象评估为基元,以便我可以对它们应用简单的操作?同样,如何在implicit conversions中使用Scala

4 个答案:

答案 0 :(得分:6)

您可以实施__add__来定义课程中的添加内容。

class A(object):
    def __init__(self, value):
       self.value = value
    def __repr__(self):
       return 'A(%r)'%self.value
    def __add__(self, other):
       return A(self.value+other.value)

>>> A(1)+A(2)
A(3)

此实现假定您只是尝试将A的实例添加到A的其他实例以获取A的第三个实例。您可以编写一个__add__,以适应您需要它的操作数类型。

另请参阅__radd____iadd__

答案 1 :(得分:2)

这取决于你想要做什么。您可以通过定义+方法来定义__add__运算符:

class A(object):
   def __init__(self, value):
       self.value = value

   def __repr__(self):
       return value

   def __add__(self, other):
       return A(self.value + other.value)

然后当然在你的示例代码中,你试图将它与一个也需要定义的整数进行比较 - 这是通过实现__eq__方法完成的:

   def __eq__(self, other):
       try:
          self.value == other.value
       except AttributeError: # other wasn't of class A, try to compare directly instead 
          return self.value == other

(另一方面隐含的类型转换据我所知不可用)

答案 2 :(得分:0)

问题是表达式中没有足够的上下文来决定应该将对象转换为什么。 Python various methods that can be defined on an object实现了各种运算符,包括__add__()__radd__()方法。

答案 3 :(得分:0)

没有足够的上下文知道foo应该等同于foo.value,所以使用Python的哲学explicit is better than implicit。你当然可以继承int,但是运算符不会生成你的新类,并且对象本身将保持不可变(通常是Python中的数字)。值得注意的是,诸如c_int32之类的ctypes具有类似于您的示例的值属性,但不实现数字运算符。