Seite 1 von 1

Befehl aus einem String lesen

Verfasst: Samstag 2. Juni 2018, 23:05
von PhysicPat
Hallo,

ich bin recht neu bei Python und wollte fragen ob es möglich ist, einen Befehl aus einem String auszulesen, das heißt:

Code: Alles auswählen

problem = "wetter()"
Wobei der Befehl - wetter() - definiert wurde und unter direkter Ansprache ausgeführt wird. Da problem hier ein string ist wird der Befehl nicht ausgeführt.
Aus einem anderen Befehl erhalte ich über return den String problem.


Ich hoffe ihr versteht die Frage und könnte mir helfen.

MfG

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 01:15
von sls
Du solltest dir überlegen, ob du nicht ein Mapping für deine problem-Typen implementierst, z.B. über ein Dictionary. So kannst du die Funktionen den Strings explizit zuordnen:

Code: Alles auswählen

>>> def wetter():
...     print("Wir haben schönes Wetter!")
...
>>> mapping = {"wetter()": wetter}
>>> problem = "wetter()"
>>> mapping.get(problem).__call__()
Wir haben schönes Wetter!

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 08:06
von narpfel
@sls: Warum rufst du `get` nicht auch mit `__call__` auf ‽ Und um konsequent zu sein, müsstest du `print` auch nur so verwenden:

Code: Alles auswählen

print.__call__("Hello World")
Dann stellt sich natürlich die Frage, warum du die `__call__`-Methode nicht mit `__call__` aufrufst:

Code: Alles auswählen

print.__call__.__call__("Hello World")
Außerdem ist ein `get` auf einem Dictionary ohne sinnvollen Defaultwert nicht sinnvoll, weil man damit den `KeyError`, den man bekommen würde, unterdrückt und einen Fehler an einer anderen Stelle bekommt, wenn man versucht, das `None` zu verwenden.

Die einfache Lösung wäre natürlich, das redundante `__call__`und das unsinnige `get` einfach wegzulassen:

Code: Alles auswählen

mapping["wetter()"]()

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 08:37
von sls
@narpfel: mir war nicht klar, dass man direkt an das dict einen Funktionsaufruf mit den Klammern starten kann, das macht die Sache ja wesentlich entspannter. Das get() ist sinnlos, was ich eigentlich wollte war das hier:

Code: Alles auswählen

mapping[problem].__call__()
Danke für den Tipp.

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 09:48
von Sirius3
Je nach Anwendungsfall kann es ja einen sinnvollen Default geben:

Code: Alles auswählen

def wetter():
    print("Wir haben schönes Wetter!")

def unknown():
    print("Befehl unbekannt!")

mapping = {"wetter()": wetter}

problem = "regen()"
mapping.get(problem, unknown)()

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 11:02
von PhysicPat
Danke für die schnellen Antworten.

Eine andere Möglichkeit ein String zu "ent-Stringen" gibt es also nicht? Ohne das mapping zu verwenden.

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 11:15
von nezzcarth
PhysicPat hat geschrieben: Sonntag 3. Juni 2018, 11:02 Eine andere Möglichkeit ein String zu "ent-Stringen" gibt es also nicht? Ohne das mapping zu verwenden.
Keine, die man verwenden sollte. Das, was dir vorgeschlagen wurde, ist schon die beste Variante. Die Idee, irgendetwas "ent-stringen", d.h. Code in einer Zeichenkette interpretieren zu wollen ist zumindest in Python in der überwiegenden Anzahl aller Fälle schon vom Ansatz her falsch.

Re: Befehl aus einem String lesen

Verfasst: Sonntag 3. Juni 2018, 13:51
von Sirius3
@PhysicPat: was ist das eigentliche Problem, das Du zu lösen versuchst? Vielleicht ist der String ja schon der falsche Weg.