Frage
Ich habe eine Vector
Klasse definiert, die drei Eigenschaftsvariablen auf: x
, y
und z
. Koordinaten hat reelle Zahlen sein, aber es gibt nichts, was man zu tun, die folgenden zu stoppen:
>>> v = Vector(8, 7.3, -1)
>>> v.x = "foo"
>>> v.x
"foo"
Ich kann mit der "Typsicherheit" wie folgt implementieren:
import numbers
class Vector:
def __init__(self, x, y, z):
self.setposition(x, y, z)
def setposition(self, x, y, z):
for i in (x, y, z):
if not isinstance(i, numbers.Real):
raise TypeError("Real coordinates only")
self.__x = x
self.__y = y
self.__z = z
@property
def x(self):
return self.__x
@property
def y(self):
return self.__y
@property
def z(self):
return self.__z
... aber das scheint un-Pythonic.
Verbesserungsvorschläge?
Lösung
Sie haben sich zu fragen, warum Sie zu Testtyp möchten diese Werte auf Einstellung. heben Sie einfach eine TypeError
in jeder Berechnung, die den falschen Wert Typ stolpern passiert. Bonus:. Standardoperationen dies bereits tun
>>> 3.0 / 'abc'
Traceback (most recent call last):
File "<stdin>", line 1, in ?
TypeError: unsupported operand type(s) for /: 'float' and 'str'
Andere Tipps
Duck Typing ist die übliche Art und Weise in Python. Es sollte mit etwas Arbeit verhält wie eine Zahl, aber nicht notwendigerweise eine reelle Zahl.
In den meisten Fällen in Python sollte man nicht explizit für Typen überprüfen. Sie gewinnen Flexibilität, da der Code mit benutzerdefinierten Datentypen verwendet werden können, solange sie korrekt verhalten.
Die anderen Antworten bereits darauf hingewiesen, dass es nicht viel Sinn macht, hier für den Typ zu überprüfen. Darüber hinaus werden Ihre Klassen sehr schnell sein, wenn es in reinem Python geschrieben ist.
Wenn Sie eine pythonic Lösung wollen - Sie Eigenschaft verwenden könnte Setter wie:
@x.setter
def x(self, value):
assert isinstance(value, numbers.Real)
self.__x = value
Die assert-Anweisung wird entfernt, wenn Sie deaktivieren das Debuggen oder ermöglichen die Optimierung Modus.
Alternativ können Sie value
zu Floating-Point in dem Setter erzwingen.
@x.setter
def x(self, value):
self.__x = float(value)
Aber es gibt nichts zu eins zu tun, die folgende Stop:
Ich glaube, versuchen, jemanden daran zu hindern, so etwas wie das zu tun ist un-Pythonic. Wenn Sie müssen, dann sollten Sie prüfen, für Typ-Sicherheit in alle Operationen, die Sie tun könnten Vector
verwenden, meiner Meinung nach.
Um G.V.R zu zitieren:
Wir sind alle Erwachsenen.
, nachdem alle. Sehen Sie diese Frage und seine Antworten für weitere Informationen.
Ich bin sicher, erfahreneren Pythonistas hier können Sie bessere Antworten geben.
Sie sind nicht bieten Typsicherheit diese Art und Weise soll. Ja, kann jemand absichtlich den Code brechen, indem Werte, für die Ihr Behälter Versorgung wird nicht funktionieren - aber das ist genau das gleiche mit anderen Sprachen. Und selbst wenn jemand den richtigen Wert für einen Parameter in ein Verfahren oder Elementfunktion bedeutet, setzte nicht unbedingt es nicht kaputt ist: Wenn ein Programm eine IP-Adresse erwartet, aber Sie einen Hostnamen übergeben, wird es noch nicht, obwohl beide sein Strings.
Was ich sagen will ist: Die Einstellung von Python von Natur aus unterschiedlich ist. Duck Typing im Grunde sagt: Hey, ich bin nicht auf bestimmte Arten beschränkt, sondern auf die Schnittstelle, oder das Verhalten von Objekten. Wenn ein Objekt, wie es ist Handlung ist die Art von Objekt, das ich erwarten würde, ist mir egal -. Nur für ihn gehen
Wenn Sie versuchen, Typprüfung einzuführen, sind Sie im Grunde eine der nützlichsten Funktionen der Sprache zu begrenzen.
That being said, die Sie wirklich brauchen in Testgetriebene Entwicklung zu bekommen, oder Unit-Tests zumindest. Es gibt wirklich keine Entschuldigung, nicht mit dynamischen Sprachen zu tun - es bewegt sich nur die Art und Weise (Art) Fehler zu einem anderen Schritt in den Build-Prozess erfasst werden, weg von der Kompilierung eine Testsuite mehrere Male am Tag zu laufen. Während dies wie Mehraufwand scheint, wird es tatsächlich Zeit zum Debuggen und Befestigungs Code ausgegeben reduzieren, da es sich um ein von Natur aus leistungsfähigeren Weg, Fehler im Code zu erkennen.
Aber genug davon, ich bin schon weitläufig.