Создание моего собственного «целочисленного» объекта в Python

По сути, я хочу иметь возможность сделать что-то вроде:

a = Integer(1) a += 1 print a 

И, конечно, напечатать номер два в качестве результата. Какие методы мне нужно создать, чтобы получить это поведение в моем классе Integer?

Отказ от ответственности: я не планирую использовать это для «реального», просто любопытно.

Это простой и неполный пример. Посмотрите на методы __sub__ , __div__ и т. Д.

 class Integer(object) : def __init__(self, val=0) : self._val = int(val) def __add__(self, val) : if type(val) == Integer : return Integer(self._val + val._val) return self._val + val def __iadd__(self, val) : self._val += val return self def __str__(self) : return str(self._val) def __repr__(self) : return 'Integer(%s)' %self._val 

затем

 n = Integer() print n m = Integer(7) m+=5 print m 

EDIT зафиксировано __repr__ и добавлено __iadd__ . Благодаря @Keith для указания проблем. EDIT Исправлено __add__ чтобы добавить дополнение между целыми.

Во-первых, быстро просмотрите документацию в справочном руководстве по эмуляции числовых типов .

(Не слишком зацикливайтесь на этом – это просто дать вам некоторое представление о методах, лежащих в основе арифметических операций в Python)

Затем обратитесь к документации для модуля numbers , которая включает в себя все абстрактные базовые классы, которые наиболее важны для эмуляции разных типов чисел (например, numbers.Integral для пользовательских целых чисел).

Если вы хотите перегрузить операторы метода по умолчанию, используемого по умолчанию, фраза, которую вы ищете, – это «магические методы». Это методы, называемые « __<name>__ » и используемые python в случаях, отличных от прямых вызовов метода. Вы бы хотели определить методы __add__ и __str__ для своего класса, чтобы они соответствовали строкам 2 и 3 соответственно.

Стоит отметить, что метод __add__ будет вызываться, если ваш новый тип является левым операндом, и любой тип может быть передан как его аргумент. Для случаев, когда ваш является правильным операндом, вы также должны определить метод __radd__ . Это касается всех двоичных операторов.

Более подробный список магических методов для числового типа см. В разделе Emulating Numeric Types .

Я предполагаю, что вы хотите, чтобы ваш класс Integer изменялся. Чтобы получить ваш пример, это будет работать:

 class Integer(object): def __init__(self, num): self._val = num def __iadd__(self, other): self._val += int(other) def __str__(self): return str(self._val) 

Вы можете использовать перегрузку оператора :

 class Integer: def __init__(self, value): self.value = value def __repr__(self): return str(self.value) def __add__(self, value): self.value += value return self a = Integer(2) print a a = a+3 print a a += 4 print a 
 class Integer(object): def __init__(self, value=0): self._value = int(value) def __add__(self, other): if isinstance(other, Integer): return Integer(self._value + other._value) return Integer(self._value + other) def __iadd__(self, other): if isinstance(other, Integer): self._value += other._value else: self._value += other return self def __sub__(self, other): if isinstance(other, Integer): return Integer(self._value - other._value) return Integer(self._value - other) def __isub__(self, other): if isinstance(other, Integer): self._value -= other._value else: self._value -= other return self def __mul__(self, other): if isinstance(other, Integer): return Integer(self._value * other._value) return Integer(self._value * other) def __div__(self, other): if isinstance(other, Integer): return Integer(self._value / other._value) return Integer(self._value / other) def __str__(self): return str(self._value) def __int__(self): return self._value def __float__(self): return float(self._value) def __repr__(self): return 'Integer(%s)' % self._value