int
and math.trunc
have a somewhat similar relationship as str
and repr
. int
delegates to a type's __int__
method, and falls back to the __trunc__
method if __int__
is not found. math.trunc
delegates to the type's __trunc__
method directly and has no fallback. Unlike __str__
and __repr__
, which are always defined for object
, both int
and math.trunc
can raise errors out of the box.
For all the built-in types that I am aware of, both __int__
and __trunc__
are defined sensibly where appropriate. However, you can define your own set of test classes to see what errors you get:
class A:
def __int__(self):
return 1
class B:
def __trunc__(self):
return 1
class C(): pass
math.trunc(A())
and math.trunc(C())
will both raise TypeError: type X doesn't define __trunc__ method
. int(C())
will raise TypeError: int() argument must be a string, a bytes-like object or a number, not 'C'
. However, int(A())
, int(B())
and math.trunc(B())
will all succeed.
In the end the decision as to which method to use is one of connotation. trunc
is inherently a math operation similar to floor
, while int
is a general purpose conversion, and succeeds in more cases.
And don't forget about operator.index
and the __index__
method.