Предварительная обработка текста функции во время компиляции bofore
Я решил попытаться предварительно обработать текст функции перед ее компиляцией в байт-код и после выполнения. Это просто для тренировки. Я с трудом представляю ситуации, когда это будет удовлетворительное решение для использования. Я столкнулся с одной проблемой, которую я хотел решить таким образом, но в конечном итоге был найден лучший способ. Так что это только для обучения и изучения чего-то нового, а не для реального использования.
Предположим, у нас есть функция, исходный код которой мы хотим немного изменить перед компиляцией:
def f():
1;a()
print('Some statements 1')
1;a()
print('Some statements 2')
Позвольте, например, отметить некоторые строки этого1;
для них иногда нужно комментировать, а иногда нет. Я просто беру это к примеру, модификации функции могут быть разными.
Чтобы прокомментировать эти строки я сделал декоратор. Весь код ниже:
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()
я использовалinspect.getsourcelines восстановить функциюf
код. Затем я сделал некоторую обработку текста (в этом случае комментируя строки, начинающиеся с1;
). После этого я сохранил его вtemp.py
модуль, который затем импортируется. И тогда функцияf
оформлен в основном модуле.
Вывод, когда применяется декоратор, выглядит так:
Some statements 1
Some statements 2
когда НЕ применяется это:
a()
Some statements 1
a()
Some statements 2
Что мне не нравится, так это то, что мне приходится использовать жесткий диск для загрузки скомпилированной функции. Можно ли это сделать без записи во временный модуль?temp.py
и импорт из него?
Второй вопрос о размещении декоратора вышеf
: @replace
, Когда я делаю это,inspect.getsourcelines
возвращаетсяf
текст с этим декоратором. Я мог бы вручную удалить изf
текст. но это было бы довольно опасно, поскольку может быть применено более одного декоратора. Поэтому я прибег к синтаксису оформления старого стиляf = remove_1(f)
, который делает работу. Но все же, возможно ли разрешить нормальную технику@replace
?