prüfen ob Variable existiert

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Hallo,

habe im Internet gesucht, wie ich prüfen kann ob eine Variable bereits existiert oder nicht.
Bin auf folgende Lösung gestoßen:

Code: Alles auswählen

if "variable" not in locals():
	variable = irgendwas
Wollte fragen, ob das suchen in locals ein guter Weg ist, um zu prüfen ob eine Variable bereits existiert, oder ob es da einen besseren weg gibt?
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Es ist kein guter Weg, denn der Umstand, dass du das prüfen muss, sollte in einem Programm nie auftreten.

Warum denkst du, dass du das brauchst?
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Zum besseren Verständnis hier noch die Methode, um die es geht:

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der Aussenseiten der Figur zurück
        """
        columns = sorted({column for row, column in coords})
        if len(columns) == 1:
            left_columns = right_columns = columns
        if side == "left":
            if "left_columns" not in locals():
                left_columns = columns[:len(columns)//2]
            left_coords = [(row, column) for row, column in coords
                                         if column in left_columns
                           ]
            return left_coords
        elif side == "right":
            if "right_columns" not in locals():
                right_columns = columns[len(columns)//2:]
            right_coords = [(row, column) for row, column in coords
                                          if column in right_columns
                            ]
            return right_coords
Ich hatte es erst so:

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der Aussenseiten der Figur zurück
        """
        columns = sorted({column for row, column in coords})
        if len(columns) == 1:
            left_columns = right_columns = columns
        elif len(columns) > 1:
            left_columns = columns[:len(columns)//2]
            right_columns = columns[len(columns)//2:]
        if side == "left":
            left_coords = [(row, column) for row, column in coords
                                         if column in left_columns
                           ]
            return left_coords
        elif side == "right":
            right_coords = [(row, column) for row, column in coords
                                          if column in right_columns
                            ]
            return right_coords

Hier hatte ich aber überlegt, dass wenn side gleich "left" ist, right_columns zwar Werte zugewiesen werden, aber die Variable nicht verwendet wird und das wollte ich gerne vermeiden.

Nochmal davor hatte ich die Methode wie folgt:

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der Aussenseiten der Figur zurück
        """
        columns = sorted({column for row, column in coords})
        if side == "left":
            if len(columns) == 1:
                left_columns = columns
            elif len(columns) > 1:
                left_columns = columns[:len(columns)//2]
            left_coords = [(row, column) for row, column in coords
                                         if column in left_columns
                           ]
            return left_coords
        elif side == "right":
            if len(columns) == 1:
                right_columns = columns
            elif len(columns) > 1:
                right_columns = columns[len(columns)//2:]
            right_coords = [(row, column) for row, column in coords
                                          if column in right_columns
                            ]
            return right_coords
Hier fand ich aber, dass sich "if len(columns) == 1:" doppelt, was ich ebenfalls vermeiden wollte.
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Ich wollte halt so testen, ob die Variablen "left_columns" und "right_columns" schon erstellt wurden.

Oder ist es besser am Anfang der Methode beide Variablen mit None zu deklarieren und dann zu prüfen, ob ihr Wert nicht mehr None ist?
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Habe jetzt zwei Möglichkeiten erstellt:

Einmal eine mit der Zuweisung von None an beide Variablen:

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der Aussenseiten der Figur zurueck
        """
        left_columns = right_columns = None
        columns = sorted({column for row, column in coords})
        if len(columns) == 1:
            left_columns = right_columns = columns
        if side == "left":
            if not left_columns:
                left_columns = columns[:len(columns)//2]
            left_coords = [(row, column) for row, column in coords
                                         if column in left_columns
                           ]
            return left_coords
        elif side == "right":
            if not right_columns:
                right_columns = columns[len(columns)//2:]
            right_coords = [(row, column) for row, column in coords
                                          if column in right_columns
                            ]
            return right_coords
Und eine mit tenärem if:

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der Aussenseiten der Figur zurueck
        """
        columns = sorted({column for row, column in coords})
        if side == "left":
            left_columns = (columns if len(columns) == 1 else
                            columns[:len(columns)//2]
                            )
            left_coords = [(row, column) for row, column in coords
                                         if column in left_columns
                           ]
            return left_coords
        elif side == "right":
            right_columns = (columns if len(columns) == 1 else
                             columns[len(columns)//2:]
                             )
            right_coords = [(row, column) for row, column in coords
                                          if column in right_columns
                            ]
            return right_coords
Hier doppelt sich aber auch wieder die Zeile "columns if len(columns) == 1 else", oder ist das keine wirkliche Codedopplung?

Finde auf jeden Fall, dass sich die zweite Version recht gut lesen lässt...
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Glaube ich baue die Methode morgen Früh nochmal komplett um, die List-Comprehensions in "left" und "right" sehen ja auch nahezu identisch aus.
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Habe die Methode jetzt umgeschrieben und damit hat sich auch meine Frage erledigt, dennoch danke für deine Antwort.

Code: Alles auswählen

    @staticmethod
    def outside_coords(side, coords):
        """
        gibt die Koordinaten der linken oder rechten
        Aussenseite der Figur zurueck
        """
        columns = sorted({column for row, column in coords})
        if len(columns) > 1:
            columns = (columns[:len(columns)//2]
                       if side == "left" else
                       columns[len(columns)//2:]
                       )
        side_coords = [(row, column) for row, column in coords
                                     if column in columns
                       ]
        return side_coords
Benutzeravatar
sparrow
User
Beiträge: 4164
Registriert: Freitag 17. April 2009, 10:28

Und warum ist das eine statische Methode und keine Funktion?
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Weil die mit zur Klasse Human gehört und nur von dieser benötigt wird, bzw ist sie Teil eines Zuges eines Menschen. Ist ein Tetrisspiel mit Curses realisiert.
Den Computergegner habe ich noch nicht soweit, er wird diese Methode aber dennoch nicht brauchen.
Sirius3
User
Beiträge: 17711
Registriert: Sonntag 21. Oktober 2012, 17:20

Die Funktion ist halt so allgemein, dass sie wirklich nichts mit einem menschlichen Spieler zu tun hat. In Python tendiert man eher dazu einfache Funktionen statt statischer Methoden zu schreiben.
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Kann ich denn Funktionen auch in Klassen schreiben und diese dann innerhalb der Klasse verwenden?
Dachte immer, das statische Methoden sozusagen Funktionen sind, die an Klassen gebunden sind.
_Mala_Fide_
User
Beiträge: 53
Registriert: Dienstag 22. Dezember 2015, 19:17

Habe es gerade getestet indem ich @staticmethod entfernt habe und es funktioniert trotzdem alles wie vorher.
Ich glaube, dann muss ich mich nochmal etwas über statische Methoden belesen...
Antworten