Ich versuche, eine Funktion in Python zu machen, die das Äquivalent von compile() tut, aber lässt mich auch die ursprüngliche Zeichenfolge zurück. Nennen wir die beiden Funktionen comp() und decomp(), um sie voneinander zu unterscheiden. Das heißt,
a = comp("2 * (3 + x)", "", "eval")
eval(a, dict(x=3)) # => 12
decomp(a) # => "2 * (3 + x)"
Die zurückgegebene Zeichenkette muss nicht identisch ("2*(3+x)" wäre akzeptabel), aber es muss im Grunde dasselbe sein ("2 * x + 6" wäre es nicht).
Ich habe Folgendes ausprobiert nicht Arbeit:
- Setzen eines Attributs für das von compile zurückgegebene Codeobjekt. Sie können keine benutzerdefinierten Attribute für Codeobjekte festlegen.
- Unterklassifizierung von Code, damit ich das Attribut hinzufügen kann. Code kann nicht unterklassifiziert werden.
- Einrichtung eines WeakKeyDictionary, das Code-Objekte auf die ursprünglichen Zeichenketten abbildet. Code-Objekte können nicht schwach referenziert werden.
Hier ist, was funktioniert, mit Problemen:
- Übergabe der ursprünglichen Codezeichenkette für den Dateinamen an compile(). Allerdings verliere ich die Fähigkeit, tatsächlich einen Dateinamen dort zu halten, die ich auch tun möchte.
- Beibehaltung eines echten Wörterbuchs, das Codeobjekte auf Zeichenketten abbildet. Dies leckt Speicher, obwohl seit Kompilieren ist selten, es ist akzeptabel für meinen aktuellen Anwendungsfall. Ich könnte wahrscheinlich laufen die Schlüssel durch gc.get_referrers regelmäßig und töten aus toten, wenn ich musste.