В Python 3 деление целых чисел или чего-либо, включая число с плавающей запятой, приводит к числу с плавающей запятой:
>>> from fractions import Fraction
>>> f = Fraction(1, 2)
>>> f / 2
Fraction(1, 4)
>>> 2 / f
Fraction(4, 1)
>>> 1 / 2
0.5
>>> 2 / 1
2.0
>>> f / .1
5.0
>>> f / .2
2.5
>>> .2 / f
0.4
Я хотел бы, чтобы деление возвращало дроби, т. Е. Получало следующее поведение:
>>> 1 / 2
Fraction(1, 2)
>>> 2 / 1
Fraction(2, 1)
Я безуспешно пытался переопределить разделение:
>>> int.__truediv__ = lambda self, other: Fraction(self) / Fraction(other)
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
TypeError: can't set attributes of built-in/extension type 'int'
Каковы мои варианты? Я согласен представить класс MyFraction
, производный от Fraction. По крайней мере, я хотел бы иметь возможность определить dict
-подобный класс X
таким образом, чтобы
>>> X({'a': 1/3}) == X({'a': Fraction(1, 3)})
True
N.B.: Кажется, изначально описанное мной поведение было задумано (см. PEP 238):
Если и когда в Python добавлен рациональный тип (см. PEP 239), истинное деление на целые и длинные числа, вероятно, должно возвращать рациональное число. Это позволяет избежать проблемы с истинным разделением целых и длинных значений с потерей информации. Но до тех пор, для согласованности, float — единственный выбор для истинного деления.
int
(что означает, что вы не сможете использовать целочисленные литералы). Сначала приведите свои операнды кFraction
объектам. - person Martijn Pieters   schedule 14.06.2013