Running Python-Code in einem String enthalten

Ich schreibe eine Spielmaschine mit pygame und box2d, und im Charakter-Builder möchte ich den Code schreiben können, der bei Keydown-Events ausgeführt wird.

Mein Plan war, einen Texteditor im Charakter-Erbauer zu haben, der Ihnen erlaubt, Code zu schreiben, der ähnlich ist:

if key == K_a: ## Move left pass elif key == K_d: ## Move right pass 

Ich werde den Inhalt des Texteditors als String abrufen, und ich möchte, dass der Code in einer Methode in dieser Methode von Character ausgeführt wird:

 def keydown(self, key): ## Run code from text editor 

Was ist der beste Weg, das zu tun?

4 Solutions collect form web for “Running Python-Code in einem String enthalten”

Sie können die Methode eval(string) verwenden, um dies zu tun.

Definition

eval(code, globals=None, locals=None)
Der Code ist nur Standard-Python-Code – das bedeutet, dass es immer noch richtig eingerückt werden muss.

Die Globalen können eine benutzerdefinierte __builtins__ definiert haben, die für Sicherheitszwecke nützlich sein könnten.

Beispiel

 eval("print('Hello')") 

hello an die Konsole. Sie können auch lokale und globale Variablen für den zu verwendenden Code angeben:

 eval("print('Hello, %s'%name)", {}, {'name':'person-b'}) 

Sicherheitsbedenken

Sei vorsichtig. Jede Benutzereingabe wird ausgeführt. Erwägen:

 eval("import os;os.system('sudo rm -rf /')") 

Es gibt eine Reihe von Möglichkeiten um das. Am einfachsten ist es, so etwas zu tun:

 eval("import os;...", {'os':None}) 

Was eine Ausnahme auslösen wird, anstatt deine Festplatte zu löschen. Während dein Programm Desktop ist, könnte dies ein Problem sein, wenn Leute Skripte neu verteilen, was ich mir vorstelle, ist beabsichtigt.

Merkwürdiges Beispiel

Hier ist ein Beispiel für die Verwendung von eval ziemlich seltsam:

 def hello() : print('Hello') def world() : print('world') CURRENT_MOOD = 'happy' eval(get_code(), {'contrivedExample':__main__}, {'hi':hello}.update(locals())) 

Was dies auf der Streitlinie bedeutet, ist:

  1. Gibt dem aktuellen Modul einen anderen Namen (es wird contrivedExample für das Skript). Der Verbraucher kann jetzt contrivedExample.hello() anrufen.)
  2. Es definiert hi als Hinweis auf hello
  3. Es kombinierte dieses Wörterbuch mit der Liste der aktuellen globals im ausführenden Modul.

FEHLSCHLAGEN

Es stellt sich heraus (danke Kommentatoren!), Dass man eigentlich die exec Anweisung verwenden muss. Große oops Die überarbeiteten Beispiele sind wie folgt:


exec Definition

(Das sieht vertraut aus!) Exec ist eine Aussage:
exec "code" [in scope] Wo Bereich ist ein Wörterbuch von lokalen und globalen Variablen. Wenn dies nicht angegeben ist, wird es im aktuellen Bereich ausgeführt.

Der Code ist nur Standard-Python-Code – das bedeutet, dass es immer noch richtig eingerückt werden muss.

exec Beispiel

 exec "print('hello')" 

hello an die Konsole. Sie können auch lokale und globale Variablen für den zu verwendenden Code angeben:

 eval "print('hello, '+name)" in {'name':'person-b'} 

exec Sicherheit Bedenken

Sei vorsichtig. Jede Benutzereingabe wird ausgeführt. Erwägen:

 exec "import os;os.system('sudo rm -rf /')" 

Druckerklärung

Wie auch von Kommentatoren festgestellt, ist print eine Anweisung in allen Versionen von Python vor 3.0. In 2.6 kann das Verhalten durch Eingabe from __future__ import print_statement . Andernfalls verwenden Sie:

 print "hello" 

Anstatt von :

 print("hello") 

Wie andere schon erwähnt haben, kannst du den Text in einen String laden und exec "codestring" . Wenn es bereits in einer Datei enthalten ist, wird das Verwenden von execfile es vermeiden, es zu laden.

Eine Leistungsnote: Sie sollten vermeiden, den Code mehrmals auszuführen, da das Parsen und das Kompilieren der Python-Quelle ein langsamer Prozess ist. Dh Nicht haben:

 def keydown(self, key): exec user_code 

Sie können dies ein wenig verbessern, indem Sie die Quelle in ein Codeobjekt compile() (mit compile() und führen Sie das oder besser, indem Sie eine Funktion compile() , die Sie herumhalten und nur einmal bauen. Entweder erfordern Sie den Benutzer, "def my_handler ( Args …) ", oder setzen Sie es selbst vor und machen Sie etwas wie:

 user_source = "def user_func(args):\n" + '\n'.join(" "+line for line in user_source.splitlines()) d={} exec user_source in d user_func = d['user_func'] 

Dann später:

 if key == K_a: user_func(args) 

Sie können eval()

Eval oder exec Sie sollten unbedingt Python-Bibliotheksreferenz vor der Programmierung lesen.

  • Warum wird dieses Spiel nicht starten, es ist Looping
  • Python Pygame Kamera Bewegung
  • Wie man Grenzen für die Größenänderung eines Fensters in pygame setzt
  • Pygame Sichtlinie aus fester Position
  • Starten Sie das Ereignis, wenn die Schaltfläche mit pygame angeklickt wird
  • Pygame: Mausspezifische Achserkennung
  • Mit dem Python-Multiprocessing-Modul für IO mit pygame auf Mac OS 10.7
  • Pygame brach zusammen?
  • Pygame-Ereigniswarteschlange
  • Stapeln von verschiedenen Arten von Transparenz in Pygame
  • PyGame-Zeichen geht aus
  • Python ist die beste Programmiersprache der Welt.