2009-10-28 12 views
5

Dato è il seguente esempio:pitone Classe con emulazione intero

class Foo(object): 
    def __init__(self, value=0): 
     self.value=value 

    def __int__(self): 
     return self.value 

voglio avere una classe Foo, che agisce come un intero (o float). Quindi voglio fare le seguenti cose:

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

La prima affermazione print int(f)+5 sta lavorando, perche 'ci sono due numeri interi. Il secondo sta fallendo, perché devo implementare __add__ per fare questa operazione con la mia classe.

Quindi per implementare il comportamento intero, devo implementare tutti i metodi di emulazione interi. Come potrei aggirare questo. Ho provato ad ereditare da int, ma questo tentativo non ha avuto successo.

Aggiornamento

Ereditando da int fallisce, se si desidera utilizzare 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) 

Se poi si chiama:

f=Foo(some_argument=3) 

si ottiene:

testato con Python 2.5 e 2.6

+1

Non capisco la tua domanda. Come puoi aggirare l'unica cosa che devi fare per non fare l'unica cosa che devi fare? Fishslap! –

+0

Voglio un atto di classe come un numero intero. Le implementazioni per i numeri interi reali sono sempre le stesse, quindi perché implementarle ogni volta che la si utilizza. Il metodo __add__ ha senso quando si utilizza l'operatore '+' - per tutto ciò che non è un'aggiunta reale. –

risposta

5

È necessario eseguire l'override __new__, non __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 

Ora il vostro lavoro di classe come previsto:

>>> 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 

Maggiori informazioni su sovrascrivendo new può essere trovato in Unifying types and classes in Python 2.2.

7

In Python 2.4+ ereditando da int funziona:

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

Ho avuto problemi quando stavo usando argomenti con nome per il costruttore (__init__). Quando chiamo f = MyInt (other_argument = True) non funzionava (TypeError: 'other_argument' è un argomento parola chiave non valido per questa funzione) –

+1

@ Günther Jehle: per favore aggiungi questo alla tua domanda. Questo commento non quadra con la tua domanda, e non ha molto senso nel contesto di questa domanda. Si prega di aggiornare la domanda per includere tutti i fatti. –

+0

aggiunto il risultato di ereditare da int –

2

tenta di utilizzare una versione up-to-date di pitone. Il tuo codice funziona in 2.6.1.

+0

Provero 'questo –

+0

La mia versione python è attualmente 2.5.1 –

+0

Aspetta, perché stai ereditando da 'object' ?? Il codice funziona se si eredita da 'int'. – jdb