Dynamische Library - For_Schleife unterschiedliche Variablen erzeugen

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
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Nach '__deets__' Beitrag werde ich es eben doch als neuen Thread posten. :P ^^

Undzwar möchte ich zu einem Programmen eine dynamische Library hinzufügen, da ich aber kein Server habe ,denn 1) kein Geld ausgeben will & 2) zu faul bin mir erst ein einzurichten, habe ich es so gemacht, dass ich jedes Programm (Name+URL) auf eine Seite meiner Webseite schreibe, was z.b. so aussieht:

Code: Alles auswählen

Python-Forum | www.python-forum.de
Nun könnten allerdings tausende Programme (also Name+Url - jedes Programm durch neue Zeile trennbar) da stehen, dafür habe ich folgenden Code:

Code: Alles auswählen

 for programs in online_libs:
            datas = programs.split('|')
            menu_item = QAction(QIcon("sgi_icon.png"),datas[0],self)
            menu_item.triggered.connect(lambda: webbrowser.open(datas[1]))
            self.library.addAction(menu_item)
Die Menus werden erstellt, mit Name und Url, allerdings ist auf allen Items die Url des letzten Datensatzes.
Das Warum ist mir klar, denn 'triggered.connect()' greift letztendlich nur auf 1 Variable zu.

Aber mir fällt nichts ein wie ich die Variable in der for-Schleife nach jeden Ablauf unterschiedlich erzeugen lasse.

Grüße,
xXSkyWalkerXx1
Zuletzt geändert von xXSkyWalkerXx1 am Dienstag 9. Juli 2019, 10:09, insgesamt 1-mal geändert.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

split liefert schon eine Liste mit Strings, das nochmalige Umwandeln in einen String ist also unsinnig. Und zwei splits sind einer zu viel.

Und das Problem wird hier alle paar Wochen mal wieder diskutiert, dass `lambda` keinen eigenen Namensraum aufmacht. Nutze functools.partial.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Okay, danke! Hab das gleich Mal im Post geändert.

Werd mich dazu belesen...
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ich verstehe zwar nicht so genau, was fuer dich eine "dynamische Library" ist - denn im Kontext von Programmieren versteht man darunter etwas komplett anderes.

Wie dem auch sei, dein Problem ist ein alter Bekannter: captures in Python fangen den NAMEN, nicht den WERT zu dem Zeitpunkt an dem sie erzeugt wurden. Und dein lambda ist ein Capture, denn es bezieht sich ja auf den ausserhalb lebenden Namen "programs".

Die Loesung ist einfach: entweder functools.partial benutzen (wurde hier schon tausendmal gezeigt). Alternativ kannst du aus dem impliziten fangen ein explizites machen:

lambda programs=programs: ...

Damit ist programs innerhalb des Lambdas an den gewuenschten Wert gebunden.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Alternativ kannst du aus dem impliziten fangen ein explizites machen: lambda programs=programs: ...

Code: Alles auswählen

for programs in online_libs:
            datas = programs.split('|')
            menu_item = QAction(QIcon("sgi_icon.png"),datas[0],self)
            menu_item.triggered.connect(lambda programs=programs: webbrowser.open(datas[1]))
            self.library.addAction(menu_item)
...klappt trotzdem nicht so wie ich es wollte, dann schaue ich mir mal das mit 'functools.partial" an.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na dann schau doch mal auf was du dich da beziehst. Kommt programs in dem Ausdruck ueberhaupt vor? Nein? Wenn nicht, warum kann das dann wohl nicht funktionieren?

War natuerlich auch mein Fehler, ich habe nur auf die Laufvariable geachtet.
Sirius3
User
Beiträge: 17754
Registriert: Sonntag 21. Oktober 2012, 17:20

Ach ja, `data` ist schon der Plural, es gibt also kein `datas`. Und der Name ist auch viel zu allgemein. Normalerweise würde man das Ergebnis von split hier gleich tupel-Entpacken.

@__deets__: war nicht Dein Fehler, weil der OP seinen Beitrag nachträglich geändert hat.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Ah. Siehste mal. :)
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Okay, hab nun Mal 'functools.partial' ausprobiert - danke, klappt super! :)
Antworten