2015-11-26 2 views
4

Например, если бы я хотел применить математические операции над объектами следующим образом:Неявные преобразования в 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.

ответ

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__.

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 

(неявные приведения типов с другой стороны, не доступен, насколько я знаю)

0

Проблема в том, что в выражении недостаточно контекста, чтобы решить, к каким объектам нужно преобразовать. Python имеет various methods that can be defined on an object, которые реализуют различные операторы, включая методы __add__() и __radd__().

0

Недостаточно контекста, чтобы знать, что foo должен быть эквивалентен foo.value, поэтому с философией Python explicit is better than implicit. Вы можете, конечно, подкласс int, но тогда операторы не будут создавать ваш новый класс, и сам объект останется неизменным (как обычно в Python). Примечательно, что ctypes, такие как c_int32, имеют атрибут value, например ваш пример, но не используют числовые операторы.

Смежные вопросы