Funktionen mit Parametern als event (tkinter)

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.
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Hallo,

ich ahbe eine Funktion, der ich mehrere Parameter übergebe, da ich nichts in der Modulebene habe. Jetzt möchte diese Funktion als event benutzen und so auch eine Tasteneingabe binden. Dafür muss ja meines Wissens nach in der Funktion event zu finden sein. Ich weiß nciht, was ich falsch mache, aber sobald ich neben meinen Parametern auch event habe spinnt das und verträgt sich nicht.

Wie kann ich das ändern?
Bisher habe ich es so gelöst, dass ich eine neue Funktion definiert habe, die nur dazu diente eine andere Funktion aufzurufen. Also ungefähr so:

Code: Alles auswählen

bestaetigen_event(event):
     bestaetigen()
Das kommt mir aber alles andere als richtig vor. Was kann ich also da machen`?
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Loster_Paddel: Man kann das in einigen Fällen mit einer ``lambda``-Funktion machen oder eventuell der originalen Funktion auch ein letztes optionales Argument geben das einfach ignoriert wird. Ansonsten muss man halt genau das machen: einen Eventhandler der einfach nur eine andere Funktion oder Methode aufruft.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Wie immer: Bitte ein (Minimal)Beispiel zeigen, wo der Fehler tatsächlich auftritt und die Original-Fehlerausgabe dazu schreiben. So stehen die Chancen auf schnelle Hilfe besser als bei einem "Wenn ich XY mache, dann spinnt das".

Kann es sein, dass du eine Funktion von einer Drittanbieter-API in einem eventbasiertem Framework (zB GUI-Toolkit) einbinden willst? Das geht ohne Zwischenschicht nicht einfach so magisch, wenn die Funktion halt gar kein Event erwartet. Du kannst dann das Signal/Callback nicht einfach so verbinden, sondern benötigst wie gesagt eine Hilfsfunktion, auch wenn es dir hässlich erscheint.
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Na gut, dann habe ich mal ein kleines testprgramm erstellt:

Code: Alles auswählen

import tkinter as tk

app = tk.Tk()
app.geometry("200x100")

def callback(event, label):
    label["text"] = "You pressed Enter"

def main():
    app.bind('<Return>', lambda: callback(label))

    label = tk.Label(app, text="")
    label.pack()

    app.mainloop()

if __name__ == '__main__':
    main()
Ich kriege den Fehlercode:
TypeError: <lambda>() takes 0 positional arguments but 1 was given

Wenn ich nicht label in der lambda Funktion übergebe, bekomme ich erstmal kein Fehlercode, es passiert dem entsprechend auch nichts. Ich muss der Funktion callback ja label übergeben, damit er damit arbeiten kann. Und schon funktioniert das Event nicht mehr. Es besteht also das Problem mit dem übergebn und event.

Eine extra Funktion mit:

Code: Alles auswählen

def hinzufuegen_event(event):
	hinzufuegen()
Auch das wird nicht funktionieren, da hinzufuegen wieder mehrere Parameter entgegennimmt, die ich ja wiederrum, damit das funktioniert aich der Funktion hinzufuegen_event übergeben: Wie komme ich aus dieser Zwickmühle raus oder ist das nicht möglich?!
Ich hoffe, dass ich das jetzt verständlicher beschrieben habe.
VG
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Zunächst einmal: Auf Modulebene sollten nur Konstanten stehen. Also festgelegte Namen, deren Wert sich während des Programmflusses nicht verändert. Und auch der Wert selbst sollte ein unveränderliches Objekt sein. Letzteres trifft bei dir nicht zu, da ``app`` ja einen Zustand hat. Habe den Teil insofern in die main() gezogen. Und dein Problem kann ich nicht wirklich nachvollziehen. So funktioniert es doch:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk

APP_GEOMETRY = "200x100"

def change_text(label):
    label["text"] = "You pressed Enter"

def main():
    app = tk.Tk()
    app.geometry(APP_GEOMETRY)

    label = tk.Label(app, text="")
    label.pack()

    app.bind('<Return>', lambda e: change_text(label))
    app.mainloop()

if __name__ == '__main__':
    main()
Die lambda-Funktion nimmt hier das erforderliche Event an und tut schlichtweg nichts damit. Der eigentliche Funktionsaufruf erfolgt nur mit dem Label und definiert auch gar nicht erst das Event als zusätzliches Argument. Soll heißen: Mit dem lambda hast du schon Tkinters Anforderung abgefrühstückt. Was dahinter passiert, ist für die Schnittstelle völlig egal, denn aus Sicht von Tkinter ist lambda der Callback. Die andere Funktion "sieht" es gar nicht (falls du das irgendwie gedacht hast).
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Okay so werde iche s machen. Ein paar Fragen habe ich trotzdem noch.
Abgesehen davon, dass hier das Problem mit dem event war, hatte ich vorher das Problem mit dem Übergeben und dass die Funktion sonst aufgerufen wird. Verhindert die lambda Funktion, dass die Funktion aufgerufen wird?
Steht das e nachm lambda für event?
Wie finde ich die "Bezeichnung" für bestimmte tasten. Das ist irgendwie sehr schwierig. Hatte mehrere Seiten gefunden, aber es hat nie richtig funktioniert. Ich bräuchte + und -, falls du die weißt...

Danke erstmal
VG
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Nee, kenne Tkinter im Speziellen nicht so gut. Dazu kann ich leider nicht viel sagen, aber es gibt ja Doku im Netz dazu.

Zu Lambda: Das ist nach außen hin eine vollwertige Funktion. Nur mit der Einschränkung, dass man nur die Rückgabe definieren kann. Wenn man mehr braucht, sollte man eine "richtige" Funktion schreiben und die dann übergeben. Das hast du ja für das Label auch genau so gemacht, Lambda fungiert hier nur als Notbehelf zwischen den Schnittstellen.

Und ja, ich war böse und habe eine Abkürzung benutzt. Du zeigst mit der Frage auch direkt, warum man das nicht tun sollte. Für mich war die Bedeutung von ``e`` eindeutig, für andere muss das halt nicht immer zutreffen. Und ganz genau, es steht für das Event. Das war ja auch der Knackpunkt hier.
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Übrigens, wenn man es objektorientiert schreibt, dann kann das mit dem Lambda wegfallen. Aber das ist natürlich nicht ganz Ohne, wenn man Einsteiger ist. Insofern für den Anfang besser beim Lambda bleiben. Hier jedenfalls eine Möglichkeit, dass in OOP zu schreiben:

Code: Alles auswählen

#!/usr/bin/env python3
import tkinter as tk

GEOMETRY = "200x100"

class App:
    def __init__(self, geometry):
        self._app = tk.Tk()
        self._app.geometry(geometry)
        self.label = tk.Label(self._app, text="")
        self.label.pack()
        self.bind_callbacks()

    def bind_callbacks(self):
        self._app.bind('<Return>', self.on_pressed_enter)
        # Weitere Callbacks ...

    def on_pressed_enter(self, event=None):
        self.label["text"] = "You pressed Enter"

    def run(self):
        self._app.mainloop()


def main():
    app = App(GEOMETRY)
    app.run()

if __name__ == '__main__':
    main()
Benutzeravatar
snafu
User
Beiträge: 6873
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Das hatte ich wohl überlesen bzw bin nicht drauf eingangen:
Loster_Paddel hat geschrieben: Sonntag 10. Juli 2022, 12:14 Verhindert die lambda Funktion, dass die Funktion aufgerufen wird?
Naja, Lambda ist halt vorgeschaltet und sieht, wie erwähnt, für Tkinter aus wie eine normaler Funktion. Wenn man mit dem Lambda-Aufruf nichts Sinnvolles definiert, dann verhindert es quasi schon den Aufruf der eigentlichen Funktion zum Verändern des Labels. Davon weiß Tkinter halt nicht magisch etwas, dass da noch eine weitere Schicht hinter dem Aufruf steht. Das ist komplett in deiner Verantwortung als Programmierer, dass der andere Callback innerhalb des Lambdas aufgerufen wird.
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Sorry, dass ich erstmal nicht antworten konnte. Unglaublich geile Hilfe von ihnen! Mein Programm ist ziemlich groß und ändert sich ziemlich schnell, weswegen ich nicht ganz wüsste, wie das in der OOP funktionieren soll. Naja erstmal will ich mein Programm endlich mal fertigstellen und der Rest regelt sich, wenn die Zeit reif ist!
Da entsteht gleich die nächste Frage 😉

Zuerst einmal zur Info, habe ich eine Klasse, die wie folgt aufgebaut ist:

Code: Alles auswählen

class Spieler:
    def __init__(self, name, punkte, siege, spiele_jemals):
        self.name = name
        self.punkte = punkte 
        self.siege = siege
        self.spiele_jemals = spiele_jemals

    def __repr__(self):
        return self.name

    def __str__(self):
        return f"Objekt {self.name} mit {self.punkte} Punkten"
    
    def punkte_leeren(self):
        self.punkte = 0
Bisher noch nichts Spektakuläres. Jetzt möchte ich mit einer Eingabe in ein Entry Fenster ein neues Objekt erstellen.
Die Eingabe habe ich so gelöst:

Code: Alles auswählen

eingabe = eingabe_fenster.get().title()
Immernoch nichts Spektakuläres. Jetzt wird es aber tricky. Ich möchte mit dem was hinter der Variable eingabe steckt das Objekt erstellen. Also dem Wert. Da bin ich auf die exec() Funktion gesteoßen. Ich weiß, dass man mit dieser Funktion auch viel Scheiße anrichten kann, aber da ich mein Programm sowieso nur selber benutzen werde, stellt das kein Problem da... Mein Objekt möchte ich so erstellen:

Code: Alles auswählen

exec("eingabe = Spieler(eingabe, 0, 0, 0)")
Jetzt komme ich zu meinem Problem. In anderen kleinen Testprogrammen hat das ohne weitere Probleme funktioniert und ich konnte damit Objekte erstellen. Seitdem ich das in meinem Hauptprogramm in einer Funktion stehen habe, funktioniert es nicht mehr und wenn ich mir eingabe danach ausgeben lasse, bzw auch den type() handelt es sich um einen String. Egal was ich mache.
Meine Funktion sieht so aus:

Code: Alles auswählen

def objekte_checken(Spieler, datei_string, eingabe, spieler_im_spiel, spieler_jemals_roh):
    if eingabe in spieler_jemals_roh.keys():
        uebergang = spieler_jemals_roh[eingabe]
        exec("eingabe = Spieler(uebergang['name'], uebergang['punkte'], uebergang['siege'], uebergang['spiele_jemals'])")
        spieler_im_spiel.append(eingabe)
        print("Spieler mit gespeicherten Daten wieder erstellt")
    else:
        exec("eingabe = Spieler(eingabe, 0, 0, 0)")
        spieler_im_spiel.append(eingabe)
        print("Komplett neu erstellt")
Das mit dem uebergang und dem spieler_jemals_roh kommt jetzt ihnnen jetzt vielleicht komisch vor. Hierbei handelt es sich um ein dictionary, in dem ich alte Objekte mit __dict__ in einem dictionary niedergeschrieben habe. Diese Funktion soll also schauen, ob es für diesen Spieler schon ein Objekt gibt. Wenn ja erstellt, der dieses mit den gespeicherten Daten (niedergeschrieben mit __dict__), wenn nicht, erstellt er ein Neues.
Das mit exec(), locals() und globals() habe ich nicht verstanden. Hat das was damit zu tun? Gibt es in dem Fall Alternativen zu exec()?
VG
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Ich mag meine Spieler ja lieber gekocht.
Vergiss einfach ganz, dass es `exec`, `locals` und `globals` überhaupt gibt. Das braucht man nie.
`Spieler` ist eine Klasse, was ist der Grund, das als Argument zu übergeben?
`objekte_checken` ist so ein nichtssagender Name. Der hilft nicht für's Verständnis.
`datei_string` wird gar nicht benutzt.
Wenn man etwas sowohl im if-Block macht, als auch im else-Block, dann kann man es einfach einmal danach machen.
Variablen sollten immer nur einen Typ haben, `eingabe` ist mal ein String und mal ein Spieler.
Und indem Du einfach `exec` ersatzlos löschst, hast Du keine Probleme mehr:

Code: Alles auswählen

def objekte_checken(eingabe, spieler_im_spiel, spieler_jemals_roh):
    if eingabe in spieler_jemals_roh:
        print("Spieler mit gespeicherten Daten wieder erstellt")
        uebergang = spieler_jemals_roh[eingabe]
        spieler = Spieler(uebergang['name'], uebergang['punkte'], uebergang['siege'], uebergang['spiele_jemals'])
    else:
        print("Komplett neu erstellt")
        spieler = Spieler(eingabe, 0, 0, 0)
    spieler_im_spiel.append(spieler)
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Loster_Paddel: Zusätzliche Anmerkungen: Die `__repr__()`-Methode sieht nicht sinnvoll aus. Konvention ist es dort entweder etwas zurück zu geben das man in Quelltext kopieren könnte um ein gleichwertiges Objekt zu erstellen, oder falls das keinen Sinn macht, eine Darstellung die in ”spitze Klammern” (``<`` und ``>``) eingefasst ist und bei der Fehlersuche nützlich sein kann. Vorgabe ist ja immerhin schon mal, dass der Datentyp enthalten ist, und da sollte man IMHO auch nicht drunter gehen.

Code: Alles auswählen

    def __repr__(self):
        return (
            f"{self.__class__.__name__}({self.name!r}, {self.punkte!r},"
            f" {self.siege!r}, {self.spiele_jemals!r})"
        )
Ich persönlich nutze ja gerne das attrs-Package, da bekommt man schon eine nette `repr()`-Darstellung wie eben gezeigt frei Haus und muss sich da nicht selbst was basteln.

Bei `objekte_checken()` würde ich `spieler_im_spiel` nicht übergeben. Das `append()` würde ich beim Aufrufer machen. Also nicht

Code: Alles auswählen

    objekte_checken(eingabe, spieler_im_spiel, spieler_jemals_roh)
    
    # sondern
    
    spieler_im_spiel.append(objekte_checken(eingabe, spieler_jemals_roh))
Und die schlecht benannte Funktion dann so (ungetestet):

Code: Alles auswählen

def objekte_checken(eingabe, spieler_jemals_roh):
    spielerdaten = spieler_jemals_roh.get(eingabe)
    if spielerdaten is None:
        print("Komplett neu erstellt")
        return Spieler(eingabe, 0, 0, 0)
    else:
        print("Spieler mit gespeicherten Daten wieder erstellt")
        return Spieler(**spielerdaten)
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Gut das habe ich anscheinend vergessen zu erklären. Ich dachte, das wäre nicht relevant.
Ich möchte die Spieler (Objekte) fürs nächste Mal fürs nächste mal speichern. Da ich ja ich ja nicht einfach ein Objekt in eine Datei zur Datenspeicherung schreiben kann und sich pickle und json nicht vertragen, kam ich auf die Idee, die einzelnen Objekte mit __dict__ in meine json Datei zu schreiben. Deswegen auch der ganze Mist mit:

Code: Alles auswählen

Spieler(uebergang['name'], uebergang['punkte'], uebergang['siege'], uebergang['spiele_jemals'])
uebergang habe ich genutzt um sozusagen das Value des Keys (Wenn vorhanden der Spielername) zu fokussieren und damit auf die einzelnen Attribute (niedergeschrieben mit __dict__) zugreifen zu können.
Der Name ist meiner Meinung nach nicht schlecht gewählt, da diese Funktion dazu dient die einzelnen Objekte nach Existenz zu checken. Die Funktion soll gucken, ob es schon ein Objekt mit dem eingegebenen Namen gibt...
Damit ist sind die if und else Blöcke auch nicht identisch. Im if Block wird ein Objekt anhand, dem Namen, hinterlegten Attributen erstellt. Deswegen auch dieses Komische:

Code: Alles auswählen

Spieler(uebergang['name'], uebergang['punkte'], uebergang['siege'], uebergang['spiele_jemals'])
Im else Block ein ganz Neues.

Nochmal zusammengefasst die Idee:
Die Funktion schaut in dem großen dictionary bestehend aus allen Spieler, die jemals am Spiel teilgenommen haben, (spieler_jemals_roh) nach, ob für diesen Namen jemals schon einmal ein Objekt erstellt wurde. Hier einmal das spieler_jemals_roh dictionary:

Code: Alles auswählen

"spieler_jemals": {"Justus": {"name": "Justus", "punkte": 70, "siege": 0, "spiele_jemals": 0}, "Klaus": {"name": "Klaus", "punkte": 55, "siege": 0, "spiele_jemals": 0}, "Jochen": {"name": "Jochen", "punkte": 87, "siege": 0, "spiele_jemals": 0}, "Peter": {"name": "Peter", "punkte": 0, "siege": 0, "spiele_jemals": 0}, "Matheo": {"name": "Matheo", "punkte": 0, "siege": 0, "spiele_jemals": 0}}
Wenn der Name gefunden wurde, und damit jemals schon einmal ein Spieler mit diesem namen existiert hat, wird der Spieler anhand den Daten von "Spieler" erstellt.
Wenn er allerdings nicht in dem Dictionary enthalten ist (elseBlock), wird ein komplett neuer Spieler mit Standartwerten erstellt. Damit sind die Blöcke ganz und gar nicht gleich...
Sirius3 hat geschrieben: Freitag 15. Juli 2022, 12:24 Variablen sollten immer nur einen Typ haben, `eingabe` ist mal ein String und mal ein Spieler.
Damit komme ich wieder zu meinem Problem: Hinter der Variable eingabe steckt ja das, was der Benutzer eingegeben hat. Mit dieser Eingabe möchte ich die Klasse erstellen. Die Klasse soll nicht spieler heißen, wie das bei dir der Fall wäre. Ich habe ja mehrere und die sollen einedeutig sein. Und da ich das mit dem, was hinter der eingabe steckt, erstellen will, stieß ich auf exec(). In meinen kleineren Programmen zum Ausprobieren hat das super funktioniert. Seitdem ich das in meinem Hauptprogramm in Funktionen stehen habe allerdings nicht mehr :/

Ich bin immer gerne offen für tips, aber ich währe ihnen auch sehr vertraut wenn sie mir bei diesem Lösungsansatz helfen könnten, auch wenn sie den vielleicht nicht als Besten sehen.
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

__blackjack__ hat geschrieben: Freitag 15. Juli 2022, 12:46 @Loster_Paddel: Zusätzliche Anmerkungen: Die `__repr__()`-Methode sieht nicht sinnvoll aus. Konvention ist es dort entweder etwas zurück zu geben das man in Quelltext kopieren könnte um ein gleichwertiges Objekt zu erstellen, oder falls das keinen Sinn macht, eine Darstellung die in ”spitze Klammern” (``<`` und ``>``) eingefasst ist und bei der Fehlersuche nützlich sein kann. Vorgabe ist ja immerhin schon mal, dass der Datentyp enthalten ist, und da sollte man IMHO auch nicht drunter gehen.
Okay da hatte ich wohl eine totale falsche Vorstellung von __repr__(). Bisher hat diese mir nur dabei geholfen, damit wenn ich eine Liste mit den Objekten ausgebe, da kein scheiß steht.
__blackjack__ hat geschrieben: Freitag 15. Juli 2022, 12:46

Code: Alles auswählen

    objekte_checken(eingabe, spieler_im_spiel, spieler_jemals_roh)
    
    # sondern
    
    spieler_im_spiel.append(objekte_checken(eingabe, spieler_jemals_roh))
Das finde ich unglaublich stark und werde ich wahrscheinlich auch so übernehmen.
Danke
Sirius3
User
Beiträge: 18279
Registriert: Sonntag 21. Oktober 2012, 17:20

Mit variablen Variablennamen kann man nicht arbeiten. Die Spieler sind ja in der Liste `spieler_im_spiel`, und darüber kannst Du auf sie zugreifen.
Was soll passieren, wenn mehrmals der gleiche Name eingegeben wird?
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Ist dann der Name, der vor dem = beim Erstellen eines Objektes steht egal? Wenn dort immer Spieler steht, entstehen da keine Dopplungen?!
Sirius3 hat geschrieben: Freitag 15. Juli 2022, 18:01 Was soll passieren, wenn mehrmals der gleiche Name eingegeben wird?
Wäre jetzt der nächste Step gewesen. Nichts außer, dass der Benutzer durch eine Info im Label darauf hingewiesen wird.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Es ist nicht egal. Mehrfache Zuweisung an den gleichen Namen sorgt im Regelfall dafür, dass das alte Objekt abgeräumt wird, wenn das nicht woanders angelegt ist.

Aber du denkst immer noch falsch. Jetzt nehmen wir mal an, dein Traum von eindeutig benannten Spieler-Variablen wird wahr. Sie heißen jetzt Spieler1-Spieler100. Und nun? Wie schreibst du denn jetzt Code, der damit was sinnvolles tut? Woher kennt denn eine Funktion most_valuable_player die 100 Namen? Hast du die alle mal auf Verdacht da reingeschrieben? Und was passiert, wenn man nur 99 eingegeben hat? Kracht dann alles?

Darum ist das Quatsch. Wenn man eine Reihe von Objekten dynamisch erzeugen und verwalten will, dann nutzt man die passenden Datenstrukturen. Listen oder Wörterbücher.
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Nein abgesehen davon, dass in Gebrauch dieses Programmes niemals so viele Spieler angelegt werden, werden diese ja in der Liste spieler_im_spiel gespeichert.
Hebt denn die Speicherung eines Objektes in eine Liste das vor dem = auf? Wenn ich jetzt nach einem bestimmten Objekt in der Liste suche, wie mache ich das dann? Bei dieser Form von Erstellung heißen ja alle Objekte spieler.

Ich dachte und denke das leider immernoch, dass das vor dem = beim Erstellen eines Objektes eindeutig sein muss. Und das ist es ja bei:

Code: Alles auswählen

spieler = Spieler(...)
nicht. Wie erkenne ich denn meine Spieler wieder? Nur nach den Attributen?
Benutzeravatar
__blackjack__
User
Beiträge: 14078
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

@Loster_Paddel: Objekte haben keine Namen. In einer Liste hat man Objekte. Ob die überhaupt irgendwann mal an einen Namen gebunden waren, und falls ja an welchen, ist den Objekten selbst völlig egal. Wenn Du ein Objekt in einer Liste suchst, musst Du die Objekte in der Liste durchgehen und … naja, musst halt Code schreiben der die irgendwie auf ein Kriterium prüft nach dem Du suchst. Und eventuell ist eine Liste nicht die richtige Datenstruktur wenn Du da regelmässig linear durch die Objekte gehen musst um etwas zu suchen.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Loster_Paddel
User
Beiträge: 39
Registriert: Samstag 16. April 2022, 20:31

Okay dann hatte ich anscheinend ein falsches Bild vom Erstellen von Objekten.
Ist ja dann total anstrengend. Was wäre denn eine Alternative? Ein Dictionary, in dem ich nur nach dem Key suche?

Noch eine Frage
Gibt es einen effizienteren Weg nach einem bestehenden Objekt zu suchen, als das?

Code: Alles auswählen

for obj in spieler_im_spiel:
    if obj.name == eingabe:
        print("Es besteht bereits ein Objekt mit diesem Namen!")
    else:
        #Objekt erstellen
        pass
Und dafür, wenn ich den Index des Objektes haben möchte um dann einfacher darauf zugreifen zu können:

Code: Alles auswählen

index = 0
for obj in spieler_im_spiel:
    if obj.name == eingabe:
        print(f"Ja es ist enthalten mit dem Index: {index}")
    index += 1
Kommt mir iregndwie komisch vor!
VG
Antworten