2009-10-28 5 views
5

Gegeben ist das folgende Beispiel:Python-Klasse mit Integer-Emulation

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

    def __int__(self): 
     return self.value 

ich eine Klasse Foo, haben will, die als eine ganze Zahl handelt (oder float). Deshalb möchte ich die folgenden Dinge tun:

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

Die erste Anweisung print int(f)+5 arbeitet, weil es zwei ganzen Zahlen. Die zweite ist fehlerhaft, weil ich __add__ implementieren muss, um diese Operation mit meiner Klasse zu machen.

Um das Integer-Verhalten zu implementieren, muss ich alle Integer-Emulationsmethoden implementieren. Wie könnte ich das umgehen? Ich habe versucht, von int zu erben, aber dieser Versuch war nicht erfolgreich.

aktualisieren

von int Vererben fehlschlägt, wenn Sie ein __init__ verwenden möchten:

class Foo(int): 
    def __init__(self, some_argument=None, value=0): 
     self.value=value 
     # do some stuff 

    def __int__(self): 
     return int(self.value) 

Wenn Sie rufen:

f=Foo(some_argument=3) 

Sie erhalten:

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

mit Python 2.5 und 2.6 getestet

+1

Ich verstehe Ihre Frage nicht. Wie kommst du um die eine Sache herum, die du tun musst, um nicht die eine Sache zu tun, die du tun musst? Fischlawine! –

+0

Ich möchte eine Klasse wie eine ganze Zahl handeln. Die Implementierungen für echte Ganzzahlen sind immer gleich, also warum implementieren Sie sie bei jeder Verwendung. Die Methode __add__ macht Sinn, wenn Sie den Operator '+' für alles andere als eine echte Addition verwenden. –

Antwort

5

Sie müssen __new__ außer Kraft zu setzen, nicht __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 

Jetzt ist Ihre Klasse wie erwartet:

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

Mehr Informationen über new Überschreiben kann in Unifying types and classes in Python 2.2 gefunden werden.

7

In Python 2.4 + von int vererben funktioniert:

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

Ich hatte Probleme, wenn ich benannte Argumente für den Konstruktor verwendete (__init__). Wenn ich f = MyInt (other_argument = True) aufruft, ist es gescheitert (TypeError: 'other_argument' ist ein ungültiges Schlüsselwort für diese Funktion) –

+1

@ Günther Jehle: Bitte fügen Sie das zu Ihrer Frage hinzu. Dieser Kommentar passt nicht zu Ihrer Frage und ist im Zusammenhang mit dieser Frage nicht sehr sinnvoll. Bitte aktualisieren Sie die Frage, um alle Fakten einzubeziehen. –

+0

hinzugefügt das Ergebnis der erben von int –

2

versuchen, eine up-to-date-Version von Python zu verwenden. Ihr Code funktioniert in 2.6.1.

+0

Ich werde dies versuchen –

+0

Meine Python-Version ist derzeit 2.5.1 –

+0

Warten, warum erben Sie von "Objekt" ?? Der Code funktioniert, wenn Sie von 'int' erben. – jdb