例如,如果我想以下列方式对对象应用数学运算:
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
。
答案 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__
,以适应您需要它的操作数类型。
答案 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具有类似于您的示例的值属性,但不实现数字运算符。