Seite 1 von 1

Funktion einer Klasse durch Variablennamen aufrufen

Verfasst: Donnerstag 18. Juli 2019, 15:58
von Hartmannsgruber
Servus liebes Forum,

es beschäftigt mich wieder eine Frage zu der ich keine Lösung finde.
Folgender Quelltext:

Code: Alles auswählen

def eingabe_erkennen(eingabe, klasse):

    def verzweigung_bei_eingabe(instanzfunktion, befehlsliste):
        if len(befehlsliste) < 2:
            befehlsliste.append(input("Suchbegriff: "))

            #klasse.anzeigen(befehlsliste[1]) -> das sollte bei der Ausgabe eigentlich ausgeführt werden
            klasse.instanzfunktion(befehlsliste[1]) # -> es sollte die Klassenfunktion "anzeigen" aufgerufen werden
            
        else:
            klasse.instanzfunktion(befehlsliste[1])            

    #zerlegen und in eine Liste schreiben    
    eingabe = eingabe.split(" ")

    if eingabe[0] == "s":
        verzweigung_bei_eingabe(anzeigen, eingabe)
    
    elif eingabe[0] == "b":
        verzweigung_bei_eingabe(bestellen, eingabe)

def main():    
    A = Klasse()    
    while True:
    #Eingabeformat: "s" Leerzeichen "Zeichenkombination" -> s abc
        eingabe = input("Eingabe: ")
        eingabe_erkennen(eingabe, A)

                      
if __name__ == "__main__":
    main()
Ich erhalte immer als Fehler einen AttributeError: 'Klasse' object has no attribute 'instanzfunktion'
Warum übernimmt er nun nicht den Wert der Variablen "instanzfunktion"?

Ich bitte um Hilfe, zumal ich leider nichts im Internet noch in meinen Büchern finden kann.

Re: Funktion einer Klasse durch Variablennamen aufrufen

Verfasst: Donnerstag 18. Juli 2019, 16:05
von Sirius3
Woher soll Python wissen, dass genau an dieser Stelle `anzeigen` ein Verweis auf eine Instanzmethode ist, aber `eingabe` nicht.

Bei Deinem Beispiel ist die Lösung doch ganz einfach, Du übergibst wirklich die Instanzmethode:

Code: Alles auswählen

def eingabe_erkennen(eingabe, klasse):
    def verzweigung_bei_eingabe(instanzfunktion, befehlsliste):
        if len(befehlsliste) < 2:
            befehlsliste.append(input("Suchbegriff: "))
        instanzfunktion(befehlsliste[1])            

    #zerlegen und in eine Liste schreiben    
    eingabe = eingabe.split(" ")
    if eingabe[0] == "s":
        verzweigung_bei_eingabe(klasse.anzeigen, eingabe)
    elif eingabe[0] == "b":
        verzweigung_bei_eingabe(klasse.bestellen, eingabe)

Re: Funktion einer Klasse durch Variablennamen aufrufen

Verfasst: Donnerstag 18. Juli 2019, 16:53
von __blackjack__
@Hartmannsgruber: Du kommst das IMHO so ein bisschen mit den Begrifflichkeiten durcheinander. `klasse` ist gar nicht an eine Klasse gebunden sondern an ein Exemplar. Und auch „Es soll die Klassenfunktion …“ ist falsch – Du nennst es im Code selbst ja auch `instanzfunktion()`.

`befehlsliste` enthält auch keine Befehle sondern eher Argumente. Und das Wort „liste“ hat da nichts verloren.

Die kokale Funktion ist unschön. Die braucht man auch nicht wirklich. Ungetestet:

Code: Alles auswählen

COMMAND_TO_METHOD_NAME = {'s': 'anzeigen', 'b': 'bestellen'}


def eingabe_erkennen(eingabe, instance):
    if eingabe.strip():
        command, *arguments = eingabe.split()
        method_name = COMMAND_TO_METHOD_NAME.get(command)
        if method_name:
            if not arguments:
                arguments = [input('Suchbegriff: ')]
            getattr(instance, method_name)(*arguments)
    


def main():    
    instance = Klasse()
    while True:
        # Eingabeformat: 's' Leerzeichen 'Zeichenkombination' -> s abc
        eingabe_erkennen(input('Eingabe: '), instance)

Re: Funktion einer Klasse durch Variablennamen aufrufen

Verfasst: Donnerstag 18. Juli 2019, 20:42
von __blackjack__
@Hartmannsgruber: Vielleicht wäre auch das `cmd`-Modul aus der Standardbibliothek interessant für Dich. Nicht das Du am Ende so etwas selbst nachprogrammierst, wenn es das schon fertig gibt.