Question

In Python 3, division of integers, or anything including a float, results in a float:

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

I would like to get division to return Fractions, i.e., get the following behavior:

>>> 1 / 2
Fraction(1, 2)
>>> 2 / 1
Fraction(2, 1)

I have unsuccessfully tried to redefine division:

>>> 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'

What are my options? I'm ok with introducing a MyFraction class derived from Fraction. At the least I would want to be able to define a dict-like class X such that

>>> X({'a': 1/3}) == X({'a': Fraction(1, 3)})
True

N.B.: It seems that originally, the behavior I describe was the intended one (cf. PEP 238):

If and when a rational type is added to Python (see PEP 239), true division for ints and longs should probably return a rational. This avoids the problem with true division of ints and longs losing information. But until then, for consistency, float is the only choice for true division.

Was it helpful?

Solution

You probably shouldn't do this, but you can monkey-patch built-in types using the Forbidden Fruit module.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top