Classe Python con emulazione intera
-
08-07-2019 - |
Domanda
Dato è il seguente esempio:
class Foo(object):
def __init__(self, value=0):
self.value=value
def __int__(self):
return self.value
Voglio avere una classe Foo , che funge da numero 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 istruzione print int (f) +5
funziona, perché ci sono due numeri interi. Il secondo non riesce, perché devo implementare __add__
per fare questa operazione con la mia classe.
Quindi, per implementare il comportamento dei numeri interi, devo implementare tutti i metodi di emulazione dei numeri interi. Come ho potuto aggirare questo. Ho provato a ereditare da int
, ma questo tentativo non ha avuto successo.
Aggiorna
L'ereditarietà da int
non riesce, 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 chiami:
f=Foo(some_argument=3)
ottieni:
TypeError: 'some_argument' is an invalid keyword argument for this function
Testato con Python 2.5 e 2.6
Soluzione
Devi sostituire __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 la tua lezione funziona 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
Ulteriori informazioni sulla sostituzione di new
sono disponibili in Tipi e classi unificanti in Python 2.2 .
Altri suggerimenti
In Python 2.4+ eredita da int funziona:
class MyInt(int):pass
f=MyInt(3)
assert f + 5 == 8
Prova a utilizzare una versione aggiornata di Python. Il tuo codice funziona in 2.6.1.