如果 Jinja 提供设施会更容易。看起来已经完成了一些工作,但该问题目前已关闭(2019 年 11 月 20 日)并且拉取请求尚未合并。这可能是因为缩进很快就会变得很棘手(例如,想想制表符和空格。)
以下是我发现的一个简单的解决方案,它可以有效地生成 Python 代码,当然,它需要很好地处理缩进。它处理使用空格进行缩进的文件。
auto_indent()
检测宿主模板中变量的缩进级别,然后将该缩进应用于一段文本。
import os
import itertools
import jinja2
def indent_lines(text_lines: list, indent: int):
return [' ' * indent + line for line in text_lines]
def matching_line(s, substring):
lineno = s[:s.index(substring)].count('\n')
return s.splitlines()[lineno]
def is_space(c):
return c == ' '
def indentation(line: str) -> int:
initial_spaces = ''.join(itertools.takewhile(is_space, line))
return len(initial_spaces)
def auto_indent(template: str, placeholder: str, content_to_indent: str):
placeholder_line = matching_line(template, '{{ ' + placeholder + ' }}')
indent_width = indentation(placeholder_line)
lines = content_to_indent.splitlines()
first_line = [lines[0]] # first line uses placeholder indent-- no added indent
rest = indent_lines(lines[1:], indent_width)
return os.linesep.join(first_line + rest)
例子:
action_class = """\
class Actions:
def __init__(self):
pass
def prequel(self):
pass
{{ methods }}
def sequel(self):
pass
"""
inserted_methods = """\
def create_branch():
pass
def merge_branch():
pass
"""
if __name__ == '__main__':
indented_methods = auto_indent(action_class, 'methods', inserted_methods)
print(jinja2.Template(action_class).render(methods=indented_methods))
示例输出:
>>> python indent.py
class Actions:
def __init__(self):
pass
def prequel(self):
pass
def create_branch():
pass
def merge_branch():
pass
def sequel(self):
pass