Vorverarbeitung von Funktionstext in der Laufzeit, bevor er kompiliert wird

Ich habe mich entschlossen, Funktionstext vorzuverarbeiten, bevor er in Bytecode kompiliert und ausgeführt wird. Dies dient lediglich der Schulung. Ich kann mir kaum Situationen vorstellen, in denen es eine zufriedenstellende Lösung ist. Ich hatte ein Problem, das ich auf diese Weise lösen wollte, aber irgendwann wurde ein besserer Weg gefunden. Das ist also nur zum Trainieren und um etwas Neues zu lernen, nicht für den wirklichen Gebrauch.

Angenommen, wir haben eine Funktion, deren Quellcode wir vor dem Kompilieren ziemlich stark modifizieren wollen:

def f():
    1;a()
    print('Some statements 1')
    1;a()
    print('Some statements 2')

Markieren Sie zum Beispiel einige Zeilen davon mit1;, damit sie manchmal kommentiert werden und manchmal nicht. Ich nehme zum Beispiel nur an, Modifikationen der Funktion können unterschiedlich sein.

Um diese Zeilen zu kommentieren, habe ich einen Dekorateur gemacht. Der gesamte Code lautet wie folgt:

from __future__ import print_function


def a():
    print('a()')


def comment_1(s):
    lines = s.split('\n')
    return '\n'.join(line.replace(';','#;',1) if line.strip().startswith('1;') else line for line in lines)


def remove_1(f):    
    import inspect
    source = inspect.getsource(f)    
    new_source = comment_1(source)
    with open('temp.py','w') as file:
        file.write(new_source)
    from temp import f as f_new
    return f_new


def f():
    1;a()
    print('Some statements 1')
    1;a()
    print('Some statements 2')


f = remove_1(f) #If decorator @remove is used above f(), inspect.getsource includes @remove inside the code.

f()

ich benutzteinspect.getsourcelines Funktion abrufenf Code. Dann habe ich einige Textverarbeitungen durchgeführt (in diesem Fall Kommentarzeilen beginnend mit1;). Danach habe ich es gespeicherttemp.py Modul, das dann importiert wird. Und dann eine Funktionf wird im Hauptmodul eingerichtet.

Wenn der Dekorator angewendet wird, lautet die Ausgabe wie folgt:

Some statements 1
Some statements 2

wenn NICHT angewendet ist dies:

a()
Some statements 1
a()
Some statements 2

Was mir nicht gefällt ist, dass ich eine Festplatte verwenden muss, um die kompilierte Funktion zu laden. Kann es gemacht werden, ohne es in ein temporäres Modul zu schreibentemp.py und daraus importieren?

Bei der zweiten Frage geht es darum, den Dekorateur darüber zu platzierenf: @replace. Wenn ich das tue,inspect.getsourcelines kehrt zurückf Text mit diesem Dekorateur. Ich könnte manuell von gelöscht werdenf's Text. aber das wäre ziemlich gefährlich, da möglicherweise mehr als ein dekorateur angewendet wird. Also habe ich auf die altmodische Dekorsyntax zurückgegriffenf = remove_1(f), das macht den Job. Trotzdem ist es möglich, normale Dekorationstechnik mit zuzulassen@replace?

Antworten auf die Frage(2)

Ihre Antwort auf die Frage