2016-03-11 5 views
6

In Python 3.4 möchte ich eine Unterklasse von float erstellen - etwas, das in mathematischen und booleschen Operationen wie float verwendet werden kann, aber andere benutzerdefinierte Funktionalität hat und ein Argument bei der Initialisierung erhalten kann, das diese Funktionalität steuert. (Speziell wollte ich eine benutzerdefinierte __str__ und einen Parameter, der in dieser Methode verwendet wird.)Python: Kann eine Unterklasse von float zusätzliche Argumente in ihrem Konstruktor haben?

Allerdings kann ich nicht scheinen, eine Unterklasse von float zu erhalten, um einen funktionalen Konstruktor mit zwei Argumenten zu haben. Warum? Ist das eine Einschränkung für die Erweiterung von integrierten Typen?

Beispiel:

class Foo(float): 
    def __init__(self, value, extra): 
     super().__init__(value) 
     self.extra = extra 

Nun, wenn ich Foo(1,2) versuche ich bekommen:

TypeError: float() takes at most 1 argument (2 given) 

Überraschenderweise meine neue __init__ ‚Argumente sind zu erzwungen, also wenn ich Foo(1) erhalte ich:

TypeError: __init__() missing 1 required positional argument: 'extra' 

Was ist der Deal hier? Ich habe ähnliche Dinge mit Subtypen von list gemacht und war überrascht, dass es nicht auf float funktioniert.

+3

Verwandte: http://stackoverflow.com/questions/1936457/sub-classing-float-type-in- python-fails-to-catch-ausnahme-in-init –

+2

Keine Antwort auf Ihre Frage, aber eine Lösung für Ihr Problem: http://ideone.com/nIPim9 –

+0

Interessant, @ Robᵩ. Es scheint so, als würde das Überschreiben von "__new__" der Weg sein, um das zu tun, was ich will, aber nicht genau, wie ich diese Arbeit noch machen soll. –

Antwort

7

Da float unveränderbar ist, müssen Sie auch __new__ überschreiben. Folgendes sollte das tun, was Sie wollen:

class Foo(float): 
    def __new__(self, value, extra): 
     return float.__new__(self, value) 
    def __init__(self, value, extra): 
     float.__init__(value) 
     self.extra = extra 

foo = Foo(1,2) 
print(str(foo)) 
1.0 
print(str(foo.extra)) 
2 

Siehe auch Sub-classing float type in Python, fails to catch exception in __init__()

+0

Ja, das ist ein Arbeitsansatz - danke! Ich bin immer noch verwirrt, warum das notwendig ist. Für deine '__init__' Methode ist' self' ein 'float', kein' Foo', oder? Weil wir es über 'float .__ new__' erstellt haben? –

+0

Tatsächlich http://stackoverflow.com/a/13534717/204131 weist darauf hin, dass 'float .__ new__' ein Parameter von' Foo' übergeben wird, so sollte es eine Instanz von 'Foo' anstelle von float erstellen. –

3

die Lösung von cgogolin richtig ist. es ist wie so mit einer anderen unveränderlichen Klassen wie int, str ... Aber ich werde schreiben:

class Foo(float): 
    def __new__(cls, value, extra): 
     return super().__new__(cls, value) 
    def __init__(self, value, extra): 
     float.__init__(value) 
     self.extra = extra 
+0

wo ist Cgogolin? –

+0

seine Antwort ist oben – qvpham

Verwandte Themen