Как локально переопределить __truediv__ для возврата дроби
В 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
класс, полученный из фракции. По крайней мере, я хотел бы иметь возможность определить dict
подобный класс X
такой, что
>>> X({'a': 1/3}) == X({'a': Fraction(1, 3)})
True
NB. Похоже, что первоначально описанное мной поведение было намеченным (см. PEP 238):
Если и когда в Python добавляется рациональный тип (см. PEP 239), истинное деление для целых и длинных значений, вероятно, должно возвращать рациональное. Это позволяет избежать проблем с истинным разделением целых и приводит к потере информации. Но до тех пор, для последовательности, float является единственным выбором для истинного разделения.
1 ответ
Вы, вероятно, не должны этого делать, но вы можете встроить типы обезьяны-патча с помощью модуля Forbidden Fruit.