Seite 1 von 1

globals() Befehl in einer Klasse mit self verwenden

Verfasst: Freitag 28. Juli 2023, 18:51
von Borneo
Hallo alle zusammen,

ich bin relativ neu in Python und habe leider folgendes Problem:


Auf diese Weise, ohne Klassen, funktioniert der Code einwandfrei,
vor allem die Zeile "partial(globals()['meine_funktion'])('HAHA')".

from functools import partial
def meine_funktion(i):
print('=== ' + i)
partial(meine_funktion,('hihi'))()
globals()['meine_' + 'funktion']('huhu')
partial(globals()['meine_funktion'])('HAHA')


Aber sobald ich Klassen verwende, funktioniert der Befehl "globals()['self." überhaupt nicht.
Ich kriege dann die Fehlermeldung "KeyError". Ohne das Wort "self" funktioniert das sowieso
nicht innerhalb der Klasse.

from functools import partial
import tkinter as tk
def main():
root = tk.Tk()
gui = Window(root)
gui.root.mainloop()
class Window:
def __init__(self, root):
self.root = root
self.root.title("Wizard")
self.root.geometry("1920x1010+0+0")
self.root.configure(background='black')
self.meine_funktion_2()
def meine_funktion(self, i):
print('=== ' + i)
def meine_funktion_2(self):
# Diese untere Zeile funktioniert.
partial(self.meine_funktion,'Hahaha')()

# Aber die unteren 2 Zeilen funktionieren nicht.
globals()['self.meine_' + 'funktion']('huhu')
partial(globals()['self.meine_funktion'])('HAHA')
main()



Ich hoffe, ihr könnt mir helfen.
Vielen Dank schon einmal im Vorraus.

Re: globals() Befehl in einer Klasse mit self verwenden

Verfasst: Freitag 28. Juli 2023, 19:09
von sparrow
Die Antwort darauf ist einfach: Mach das nicht.
Vergiss, dass das geht.

Man baut weder Variablen- noch Funktionsnamen zusammen. Dafür gibt es keinen Grund.
Welches Problem glaubst du damit lösen zu wollen?

Re: globals() Befehl in einer Klasse mit self verwenden

Verfasst: Freitag 28. Juli 2023, 23:28
von __blackjack__
@Borneo: Ich möchte mich anschliessen: `globals()` und auf Namen über Zeichenketten zuzugreifen ist etwas das man nur sehr selten braucht. Ebenso ist `partial()` sinnlos wenn man die dadurch erstellte Funktion *sofort* aufruft. Dann hätte man auch gleich die Funktion normal aufrufen können. Auch ist `partial()` mit nur einem einzigen Argument sinnfrei, weil man da letztlich die gleiche Funktion wiederbekommt. Da muss man sich schon einen exotischen Fall konstruieren wo man aus irgendwelchen Gründen zwar eine Funktion braucht die sich gleich verhält, aber eine andere Identität hat.

Beim Beispiel mit der Klasse ist `meine_funktion_2()` überflüssig. Die Zeilen hätte man einfach mit in die `__init__()` schreiben können/sollen.

Und dann ist `meine_funktion()` tatsächlich eine Funktion, und hat damit eher nichts in der Klasse verloren.

Natürlich funktioniert das mit dem `self` nicht, denn es kann keine (reguläre) Funktion mit dem Namen "self.meine_funktion" geben, weil der Punkt in einem Namen kein gültiger Name in Python ist. Da könnte man ja auch nie normal drauf zugreifen, denn der Punkt ist ein Operator.

Und `self` selbst ist ein *lokaler* Name, da kann man natürlich auch nicht mit `globals()` drauf zugreifen.

`gui.root.mainloop()` würde man nicht machen wenn man auch direkt auf `root` Zugriff hat.

Jetzt sind wir an einem Punkt an dem `Window` nur aus der `__init__()`-Methode besteht. Damit ist die Klasse sinnlos und das wandert alles in die `main()`-Funktion.

Deren Aufruf man durch ein ``if __name__ == "__main__":`` beim Importieren verhindern sollte.

Womit wir vereinfacht ungefähr hier ankommen:

Code: Alles auswählen

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


def funktion(value):
    print("===", value)


def main():
    root = tk.Tk()
    root.title("Wizard")
    root.configure(background="black")
    for value in ["Hahaha", "huhu", "HAHA"]:
        funktion(value)
    root.mainloop()


if __name__ == "__main__":
    main()

Re: globals() Befehl in einer Klasse mit self verwenden

Verfasst: Freitag 28. Juli 2023, 23:48
von Borneo
Vielen Dank für die schnellen Antworten. Ich brauche etwas Zeit, um die Antworten vollständig zu verstehen.