Ich mache zunächst mal ein paar Anmerkungen zu deinem Code:
Zunächst solltet du dir die *-Importe abgewöhnen, die füllen dir nur den ganzen Namensraum. Häufig gibt es dabei Überschneidungen, so dass sich Namen überdecken und am Ende nicht sofort offensichtlich ist, woher welcher Namen kommt. Ein weiterer Nachteil ist, dass du im Code nicht sehen kannst, aus welchem Modul ein Name stammt. Man muss immer nachschauen.
``Point`` lässt sich viel einfacher mit numpy umsetzen als mit drei einzelnen Komponenten für x, y und z. ``numpy.matrix`` bietet sich dafür perfekt an. Zumindest sollten es aber keine einzelnen drei Variablen sein, sondern mindestens ein Tupel.
Das Ergebnis deiner add-Methode ist etwas unglücklich. Wenn man einen Punkt p und einen Punkt q addiert, dann erwartet man als Ergebnis einen Punkt. Bei dir Gibt es aber ein Tupel aus den drei Komponenten. Hier solltest du einen Punkt zurückliefern.
Auch solltest du dir die Methoden zur String-Formatierung anschauen, Strings mit + zusammensetzen ist nicht nur langsam, sondern vorallem auch sehr unübersichtlich.
Deine Fehlerbehandlung (in add) ist schlecht umgesetzt. Es ist eine ganze schlechte Idee eine Exception zu behandeln, dann eine Fehlermeldung mittels print zu schreiben und dann das Programm ganz normal weiterlaufen zu lassen. Dann wird es nämlich an einer andren Stelle krachen, da sich das Programm in einem inkonsistenten Zustand befindet. Wenn du einen Fehler nicht behandeln kannst, dann solltest du das auch nicht tun. Bei dir kommt dann noch hinzu, dass du als Fehlermeldung nur "TypeError" ausgibst. Du vernichtest also noch Information, welche bei der Fehlermeldung hilfreich sein könnte.
Und eine extrem schlechte Idee ist es, ein except zu verwenden, welches alle Exceptions abfängt. Das bedeutet nämlich tatsächlich, dass ALLE Ausnahmen abgefangen werden. Darunter fallen dann aber auch NameErrors, welche auf Programmierfehler hinweisen. Mit solch einer Ausnahmebehandlung machst du es extrem schwer Fehler zu finden.
Auch die Fehlermeldung ist unglücklich geschrieben. Wenn die Ausnahme auftritt ist nicht garantiert, dass überhaupt Elemente vom Typ Point verwendet werden (zumindest auf der rechten Seite des Operators). In deiner Fehlermeldung gehst du aber davon aus. Noch ungünstiger ist, dass du suggerierst, dass es die Typen Point1 und Point2 geben würde. Die Fehlermeldung lässt sich viel besser ausformulieren, wenn du die Repräsentation der Objekte verwendest:
Aber wie gesagt, hier solltest du gar keine Fehlerbehandlung machen, da du den Fehler offensichtlich nicht behandeln kannst.
Die Umsetzung von mul solltest du dir auch noch einmal überlegen. Hier gibt es durchaus mehrere Möglichkeiten: Skalarprodukt, Mutliplikation mit einem Skalar und komponentenweise Multiplikation.
Die str-Methode lässt sich viel einfacher umsetzen:
Die neg-Methode ist auch wieder Problematisch. Zum einen existiert die spezielle Methode __neg__ bereits für solche Sachen, die solltest du daher auch verwenden. Weiter ist Problematisch, dass du das Objekt selbst veränderst. Hier möchtest du sicher lieber ein neues Point-Objekt zurückgeben. Weiter ist es total unnötig von 0 zu subtrahieren, das Minuszeichen kann auch einfach als unärer Operator verwendet werden:
Code: Alles auswählen
def __neg__(self):
return Point(-self.x, -self.y, -self.z)
Die get-Methode hat auch wieder Schwachstellen. Wenn man auf Komponenten eines Objekts zugreifen will, dann ist __getitem__ eine gute Idee. Aber eigentlich ist get total überflüssig, da du hier nur auf x, y, und z zugreifst. In Python greift man von außen einfach darauf zu und schreibt sich nicht extra getter- und setter-Methoden. Der Grund ist ganz einfach: falls man so ein Verhalten doch mal braucht, dann verwendet man Properties. Weiter solltest du auf None nicht mit == testen, sondern mit ``is``.
``plist`` sollte besser ``PList`` oder noch besser ``Points`` oder ``PointList`` heißen. In Python sollten eigene Typen immer mit einem Großbuchstaben anfangen, schau dir mal PEP 8 an und probiere möglichst viel davon zu behalten.
Eine ganz schlechte Idee ist es von list zu erben, dies dann aber nicht zu verwenden. Wenn du von etwas erbst, dann bringt das auch jede Menge Konsequenzen mit sich und ist nicht nur ein Hinweis darauf, dass sich deine Klasse wie eine Liste verhält. Daher kommt auch dein Fehler. Einmal rufst du nämlich das append von plist auf (das ist der Funktionierende Aufruf) und einmal das append von self.list. Letzteres ist aber ein array, welches eine feste Länge hat. Das ist auch der Hauptunterschied zu Listen.
Auch ist ``list`` ein ganz schlechter Name. Zum einen verdeckt er den eingebauten Typen list zum anderen ist er total nichtssagend. Eine Name sollte immer beschreiben, was daran gebunden ist. list ist so generisch, da könnte jetzt wirklich alles drin stecken. Ähnlich nichtssagend sind wert oder wPoi.
Doppelte führende unterstriche dienen übrigens nur der Vermeidung von Namenskollisionen, einfache Unterstriche um einen Hinweise darauf zu geben, dass man ein Obejkt besser nicht anpackt, wenn man nicht genau weiß was man tut.
Über Listen kann man direkt iterieren, wenn man einen Index braucht, dann gibt es die enumerate-Funktion:
Code: Alles auswählen
for element in self.list:
if element * direction > self._highest_point_in_d:
...