Генши: Не удается получить доступ к импортированным модулям из директив в HTML - PullRequest
0 голосов
/ 05 ноября 2018

Справочная информация: Я использую Genshi для создания отчетов в формате HTML.

import genshi
import os
from genshi.template import MarkupTemplate

files = [
    r"a\b\c.txt",
    r"d/e/f.txt",
]

html = '''
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/">
        <head>
        </head>
        <body>
            <p py:for="f in sorted(files, key=lambda x: x.lower().split(os.path.sep))">
                ${f}
            </p>
        </body>
    </html>
'''
template = MarkupTemplate(html)
stream = template.generate(
    files = files
)
print(stream.render('html'))

Проблема: Генши генерирует исключение UndefinedError, потому что он не знает о модулях, которые я импортировал.

D:\SVN\OSI_SVT\0.0.0.0_swr65430\srcPy\OSI_SVT>python36 test.py
Traceback (most recent call last):
  File "test.py", line 26, in <module>
    print(stream.render('html'))
  File "C:\Python36\lib\site-packages\genshi\core.py", line 184, in render
    return encode(generator, method=method, encoding=encoding, out=out)
  ...
genshi.template.eval.UndefinedError: "os" not defined

Вопрос: Есть ли способ заставить Genshi автоматически узнавать об импортированных модулях?

Если это не возможно изначально в Genshi, я бы принял ответ, который программно создает набор импортированных модулей, чтобы они могли быть переданы в вызов generate(). Например: generate(**args)

Что я пробовал:

  • Прочитайте документацию Генши .
  • Поиск StackOverflow. Без кубиков.
  • Добавление os = os к вызову template.generate(). Это работает, но раздражает и подвержен ошибкам дублировать мой импорт.

1 Ответ

0 голосов
/ 05 ноября 2018

Я нашел способ сделать это за пределами Genshi. Этот подход добавляет все глобальные и локальные объекты (импорт, а также глобальные и локальные переменные) и добавляет их в словарь. Затем словарь передается в generate() в качестве аргументов ключевого слова (см. этот ответ , если вы не знакомы с этим).

import genshi
import os
import types
from genshi.template import MarkupTemplate

html = '''
    <html xmlns="http://www.w3.org/1999/xhtml" xmlns:py="http://genshi.edgewall.org/">
        <head>
        </head>
        <body>
            <p py:for="f in sorted(files, key=lambda x: x.lower().split(os.path.sep))">
                ${f}
            </p>
        </body>
    </html>
'''

def main():

    files = [
        r"a\b\c.txt",
        r"d/e/f.txt",
    ]

    generation_args = {}
    for scope in [globals(), locals()]:
        for name, value in scope.items():
            generation_args[name] = value

    template = MarkupTemplate(html)
    stream = template.generate(**generation_args)

    print(stream.render('html'))

main()
...