I have in my code biiiig numbers, like quadrillions and quintillions. So I build a fancy converter for them
class Repr:
def __str__(self):
# magic
return '123.456qa'
def __repr__(self):
for parent in self.__class__.__mro__:
if parent in [self.__class__, Repr]:
continue
return f'{self.__class__.__name__}' \
f'({parent.__repr__(self)})'
raise ValueError('how this is possible?')
Now I am trying to use it
class MyValue(Repr, int):
pass
v = MyValue(123.4*10**12)
print(v) # expected '123.4t'
print(f'{v!r}') # expected 'MyValue(123400000000000)'
What I fail to understand - is how MRO works if I switch parents class MyValue(int, Repr)
According to all known documentation, this should behave as int
. Because int is first, int has both __repr__
and __str__
.
That is true in the case of converting to string
class MyValue(int, Repr):
pass
v = MyValue(123.4*10**12)
print(f'{v!r}') # expected '123400000000000'
Debug shows, that Repr.__repr__
is not even used.
BUT!
Repr.__str__
is used!
print(v) # expected `123400000000000`
'123.4t' # actual result
Why do we have so much inconsistency? Why is this behavior not according to documentation?
CodePudding user response:
int
only defines its own __repr__
, not its own __str__
. It inherits __str__
from object
. When you define class MyValue(int, Repr)
, Repr
comes before object
in the MRO, so Repr.__str__
gets used instead.