2009-10-28 15 views
5

Dada es el ejemplo siguiente:Clase Python con emulación de número entero

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 número entero (o flotar). Por eso quiero hacer las siguientes cosas:

f=Foo(3) 
print int(f)+5 # is working 
print f+5 # TypeError: unsupported operand type(s) for +: 'Foo' and 'int' 

La primera declaración print int(f)+5 está trabajando, porque hay dos números enteros. El segundo está fallando, porque tengo que implementar __add__ para hacer esta operación con mi clase.

Para implementar el comportamiento de entero, 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 fue exitoso.

actualización

Heredar de int falla, si se 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 a continuación, llama a:

f=Foo(some_argument=3) 

que se obtiene:

TypeError: 'some_argument' is an invalid keyword argument for this function 

probado con Python 2.5 y 2.6

+1

No entiendo su pregunta. ¿Cómo puede evitar una cosa que tiene que hacer para no hacer lo único que tiene que hacer? Fishslap! –

+0

Quiero que una clase actúe como un entero. Las implementaciones para enteros reales siempre son las mismas, entonces, ¿por qué implementarlas cada vez que las usa? El método __add__ tiene sentido cuando usas el operador '+' para todo lo que no sea una adición real. –

Respuesta

5

Necesita 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 trabajo de clase 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 

Más información sobre anulando new se puede encontrar en Unifying types and classes in Python 2.2.

7

En Python 2.4+ heredando de int funciona:

class MyInt(int):pass 
f=MyInt(3) 
assert f + 5 == 8 
+0

Tuve problemas cuando usaba argumentos con nombre para el constructor (__init__). Cuando llamo a f = MyInt (other_argument = True) estaba fallando (TypeError: 'other_argument' es un argumento de palabra clave no válido para esta función) –

+1

@ Günther Jehle: Agregue esto a su pregunta. Este comentario no cuadra con su pregunta, y no tiene mucho sentido en el contexto de esta pregunta. Por favor, actualice la pregunta para incluir todos los hechos. –

+0

agregó el resultado de heredar de int –

2

Trate de usar una versión actualizada del pitón. Tu código funciona en 2.6.1.

+0

Voy a intentarlo –

+0

Mi versión de python es actualmente 2.5.1 –

+0

Espera, ¿por qué heredas de 'object' ?? El código funciona si heredas de 'int'. – jdb

Cuestiones relacionadas