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

¿Fue útil?

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.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top