Python Class con emulación de enteros
-
08-07-2019 - |
Pregunta
Dado es el siguiente ejemplo:
class Foo(object):
def __init__(self, value=0):
self.value=value
def __int__(self):
return self.value
Quiero tener una clase Foo , que actúa como un entero (o flotante). Entonces quiero hacer lo siguiente:
f=Foo(3)
print int(f)+5 # is working
print f+5 # TypeError: unsupported operand type(s) for +: 'Foo' and 'int'
La primera instrucción print int (f) +5
está funcionando, porque hay dos enteros. El segundo falla, porque tengo que implementar __add__
para hacer esta operación con mi clase.
Entonces, para implementar el comportamiento de enteros, tengo que implementar todos los métodos de emulación de enteros. ¿Cómo podría evitar esto? Traté de heredar de int
, pero este intento no tuvo éxito.
Update
La herencia de int
falla, si desea utilizar un __init__
:
class Foo(int):
def __init__(self, some_argument=None, value=0):
self.value=value
# do some stuff
def __int__(self):
return int(self.value)
Si luego llama:
f=Foo(some_argument=3)
obtienes:
TypeError: 'some_argument' is an invalid keyword argument for this function
Probado con Python 2.5 y 2.6
Solución
Debe anular __new__
, no __init__
:
class Foo(int):
def __new__(cls, some_argument=None, value=0):
i = int.__new__(cls, value)
i._some_argument = some_argument
return i
def print_some_argument(self):
print self._some_argument
Ahora su clase funciona como se esperaba:
>>> f = Foo(some_argument="I am a customized int", value=10)
>>> f
10
>>> f + 8
18
>>> f * 0.25
2.5
>>> f.print_some_argument()
I am a customized int
Puede encontrar más información sobre cómo anular new
en Unificación de tipos y clases en Python 2.2 .
Otros consejos
En Python 2.4+ heredando de int works:
class MyInt(int):pass
f=MyInt(3)
assert f + 5 == 8
Intente utilizar una versión actualizada de python. Su código funciona en 2.6.1.