Захват вывода из подпроцесса, но с тегами из кода, который его создал - PullRequest
0 голосов
/ 24 февраля 2020

Фон

Я пишу html книгу о том, как что-то делать в python. Он содержит тонну текста и кода с добавлением вывода. Я хочу иметь возможность изменять мой код python в любое время и иметь один сценарий для пакетного обновления всех файлов HTML с изменениями.

Поскольку у меня будет множество файлов html и тонн python фрагментов, я не могу копировать и вставлять из python в HTML вручную каждый раз, когда я что-то меняю. это будет кошмар.

Редактировать:

Итак, у меня есть два бесплатных файла: файл python, содержащий логи c и HTML файл, который является руководством для этого python кода. Я хотел бы иметь возможность редактировать мои python файлы по своему усмотрению и помечать их так, чтобы мой HTML файл также мог обновляться.

В тот момент, когда я обновляю свой код python, я просто запускаю отдельный сценарий python, который ищет в обоих файлах совпадающие теги и копирует код python между его тегами в HTML между соответствующими тегами. У меня есть много таких тегов в файлах. У меня также есть много таких пар файлов.

это теги ^ tagname и заканчиваются на ^ / tagname

Однако, это работает только для самого кода, а не для вывода кода. Я также хотел бы иметь возможность (при желании) скопировать вывод с тега python в html, чтобы он отображался внутри слегка измененного тега.

Я думал о выводе, тэге и & / тэге.

Конец редактирования

Но получаю вывод из файлов python, чтобы сделать То же самое оказывается довольно сложным.


Мой python код: (testCode.py)

#%%
# ^test
x=1
print(x)
# ^/test


#%%
print("this output I don't care about")

#%%
# ^test2
y=2
print(y)
# ^/test2

Итак, теги test и test2 - это то, что мне нужно разделить код на части.


My html выглядит следующим образом:

<p> Some text explaining the purpose of the python code in test1 </p>
<!--^test-->

<!--^/test-->



<p> some more text explaining about test2</p>
<!--^test2-->

<!--^/test2-->

Код между тегами test1 в файле python копируется между комментариями выше. И то же самое для теста 2.


Вот скриншот того, что у меня есть в моем настоящем html документе. Выглядит отлично, но отсутствует вывод.

enter image description here


Проблема в том, что я не могу понять, чтобы разделить вывод на основе тегов внутри комментариев в коде. Мне нужно использовать эти теги, чтобы разбить вывод на фрагменты, связанные с каждым тегом.


Желаемый вывод

Мой желаемый вывод - строка, такая как:

# ^test
1
# ^/test

this is output I don't care about

# ^test2
2
# ^/test2

Попытка

Я успешно захватил вывод файла в строку, используя:

python_file = 'testCode.py'
process_result = subprocess.run(['python', './' + python_file], capture_output=True, universal_newlines=True)
output = str(process_result.stdout)

, но очевидно, что просто печатает:

1
this is output I don't care about
2

Я использую подпроцесс, потому что эта функция в конечном итоге будет вызываться в al oop со списком python файлов, чтобы обновить вывод с.


Я совершенно ошарашен доступ к соответствующим тегам и вкрапление их.

Возможно, я подхожу к этому неправильно.

1 Ответ

0 голосов
/ 25 февраля 2020

Примечание: это решение работает, но грязно.

Буду признателен за любые предложения по улучшению!

Основываясь на комментарии @flakes, я нашел рабочее решение, но оно не идеально. Я уверен, что есть лучший, более элегантный способ сделать это.

Я решил немного сократить автоматизацию, чтобы также уменьшить необходимый код и сложность.

Для каждой статьи, которую я сейчас делаю есть папка, содержащая

  • ArticleName.py
  • ArticleName. html
  • ArticleName_helper.py
  • OutputFiles [Папка]

Внутри ArticleName.py я пометил код. Если я хочу сохранить выходные данные кода внутри тега, я также создаю объект OutputTag (описан ниже).

#%%
out = OutputTag('test', __file__)
# ^test
x=1
print(x)
print("test")
# ^/test
out.done()

OuputTag объект и объект для замены sdtout (сохранено в другой папке)

import os
import sys


#%%
class CustomStdout(object):
    def __init__(self, *files):
        self.files = files

    def write(self, obj):
        for f in self.files:
            f.write(obj)
            f.flush()  # If you want the output to be visible immediately

    def flush(self) :
        for f in self.files:
            f.flush()


#%%
class OutputTag:
    def __init__(self, tag, origin_file):
        origin_dir = os.path.dirname(origin_file)

        if not os.path.exists(origin_dir) :
            raise FileNotFoundError("Origin file does not exist!")

        dir = origin_dir + "/OutputFiles"
        if not os.path.exists(dir):
            os.makedirs(dir)

        file_name = os.path.join(dir, tag + '.txt')
        self.original = sys.stdout
        self.f = open(file_name, 'w')
        # This will go to stdout and the file out.txt
        sys.stdout = CustomStdout(sys.stdout, self.f)

    def done(self):
        self.f.close();
        sys.stdout = self.original

Хорошо, так что папка OutputFiles заполняется набором файлов .txt, названных в честь тегов.

Затем я запускаю сценарий ArticleName_helper.py.

  1. Имеет ссылку на файлы py и html.
  2. Вспомогательный скрипт ищет теги кода внутри ArticleName. html.
  3. Он ищет внутри ArticleName.py подходящие теги и копирует любой код между ними.
  4. Этот скопированный код затем заменяет любой существующий текст между тегами в HTML.
  5. Аналогично, он ищет выходные теги (& Tag вместо ^ Tag) в html.
  6. Ищет файлы в OutputFolder, которые соответствуют имени тега.
  7. Затем загружает текст внутри, заменяя любой текст в файле html между тегами вывода.

В моей IDE у меня есть автоматическое завершение кода. В python, когда я набираю html и нажимаю клавишу табуляции, она автоматически генерирует следующее с мульти-курсором, готовым перезаписать TAG во всех 3 точках:

out = OutputTag('TAG', __file__)
# ^TAG

# ^/TAG
out.done()

аналогично при html редактировании, я сделать так, чтобы он автоматически заполнял следующее, когда я набираю py и нажимаю tab:

<pre><code class="language-python">
    <!--^TAG-->

    <!--^/TAG-->

И аналогичный для вывода с заменой ^ на &

Итак, текущий рабочий процесс is:

  1. Запись python файл
  2. Добавление тегов, если необходимо
  3. Запись HTML учебник, добавление тегов комментариев, где это необходимо для ввода и связанного вывода.
  4. Запуск Python файла для обновления выходных данных
  5. Запуск вспомогательного сценария
  6. HTML Файл автоматически заполняется кодом и выводом, где были добавлены теги.

После внесения изменений просто выполните шаги 4-6.

Результат!

result screenshot

...