Python: overwrite __int__
Question:
A working solution, which returns integers, was given in Overload int() in Python.
However, it works only for returning int
, but not float
or let’s say a list:
class Test:
def __init__(self, mylist):
self.mylist = mylist
def __int__(self):
return list(map(int, self.mylist))
t = Test([1.5, 6.1])
t.__int__() # [1, 6]
int(t)
Thus t.__int__()
works, but int(t)
gives TypeError: __int__ returned non-int (type list)
.
Thus, is there a possibility to fully overwrite int
, maybe with __getattribute__
or metaclass
?
Answers:
From the doc of __int__
Called to implement the built-in functions complex(), int() and float(). Should return a value of the appropriate type.
Here your method return a list
and not an int
, this works when calling it explictly but not using int()
which checks the type of what is returned by the __int__
Here is a working example of what if could be, even if the usage if not very pertinent
class Test:
def __init__(self, mylist):
self.mylist = mylist
def __int__(self):
return int(sum(self.mylist))
The __int__
, __float__
, … special methods and various others do not overwrite their respective type such as int
, float
, etc. These methods serve as hooks that allow the types to ask for an appropriate value. The types will still enforce that a proper type is provided.
If required, one can actually overwrite int
and similar on the builtins
module. This can be done anywhere, and has global effect.
import builtins
# store the original ``int`` type as a default argument
def weakint(x, base=None, _real_int=builtins.int):
"""A weakly typed ``int`` whose return type may be another type"""
if base is None:
try:
return type(x).__int__(x)
except AttributeError:
return _real_int(x)
return _real_int(x, base)
# overwrite the original ``int`` type with the weaker one
builtins.int = weakint
Note that replacing builtin types may violate assumptions of code about these types, e.g. that type(int(x)) is int
holds true. Only do so if absolutely required.
This is an example of how to replace int(...)
. It will break various features of int
being a type, e.g. checking inheritance, unless the replacement is a carefully crafted type. A full replacement requires emulating the initial int
type, e.g. via custom subclassing checks, and will not be completely possible for some builtin operations.
A working solution, which returns integers, was given in Overload int() in Python.
However, it works only for returning int
, but not float
or let’s say a list:
class Test:
def __init__(self, mylist):
self.mylist = mylist
def __int__(self):
return list(map(int, self.mylist))
t = Test([1.5, 6.1])
t.__int__() # [1, 6]
int(t)
Thus t.__int__()
works, but int(t)
gives TypeError: __int__ returned non-int (type list)
.
Thus, is there a possibility to fully overwrite int
, maybe with __getattribute__
or metaclass
?
From the doc of __int__
Called to implement the built-in functions complex(), int() and float(). Should return a value of the appropriate type.
Here your method return a list
and not an int
, this works when calling it explictly but not using int()
which checks the type of what is returned by the __int__
Here is a working example of what if could be, even if the usage if not very pertinent
class Test:
def __init__(self, mylist):
self.mylist = mylist
def __int__(self):
return int(sum(self.mylist))
The __int__
, __float__
, … special methods and various others do not overwrite their respective type such as int
, float
, etc. These methods serve as hooks that allow the types to ask for an appropriate value. The types will still enforce that a proper type is provided.
If required, one can actually overwrite int
and similar on the builtins
module. This can be done anywhere, and has global effect.
import builtins
# store the original ``int`` type as a default argument
def weakint(x, base=None, _real_int=builtins.int):
"""A weakly typed ``int`` whose return type may be another type"""
if base is None:
try:
return type(x).__int__(x)
except AttributeError:
return _real_int(x)
return _real_int(x, base)
# overwrite the original ``int`` type with the weaker one
builtins.int = weakint
Note that replacing builtin types may violate assumptions of code about these types, e.g. that type(int(x)) is int
holds true. Only do so if absolutely required.
This is an example of how to replace int(...)
. It will break various features of int
being a type, e.g. checking inheritance, unless the replacement is a carefully crafted type. A full replacement requires emulating the initial int
type, e.g. via custom subclassing checks, and will not be completely possible for some builtin operations.