Jinja2-创建包含前缀列表中对象的python列表



我使用Jinja2从模板创建一个Python类。我的模板看起来像

class {{class_name}}({{base_class_name}}):

def __init__(self, {{ parameters|join(', ') }}):
{{comment}}
super().__init__()
{% for param in parameters%}
self.{{param}} = {{param}}
{%- endfor %}
{# First variant #}
self.parameters1 = {{parameter_list}}
{# Second variant #}
self.parameters2 = {{['self.'] | product(parameters) | map('join') | list}}

我的python脚本被定义为

from itertools import product
from pathlib import Path
import jinja2
def create_class_from_template():
templates_path = Path(__file__).parent / 'templates'
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path))
jinja_env.filters['product'] = product
parameters = ['param1', 'param2', 'param3']  # For first variant
parameter_list = [f'self.{param}' for param in parameters]  # For second variant
template_variables = { 
'class_name': 'TestClass',
'base_class_name': 'BaseClass',
'comment': '"""My generated class"""',
'parameters': parameters,
'parameter_list': parameter_list
}
template = jinja_env.get_template('class_template.py.jinja2')
my_class = template.render(template_variables)
with open('my_new_class.py', 'w') as file:
file.write(my_class)

create_class_from_template()

它创建了以下python文件

class TestClass(BaseClass):

def __init__(self, param1, param2, param3):
"""My generated class"""
super().__init__()

self.param1 = param1
self.param2 = param2
self.param3 = param3
self.parameters1 = ['self.param1', 'self.param2', 'self.param3']
self.parameters2 = ['self.param1', 'self.param2', 'self.param3']

但是,列表应该包含成员本身,而不是字符串,因此它是self.parameters = [self.param1, self.param2, self.param3]

有人知道我如何使用Jinja2和Python创建这样一个列表吗?

它可以在不更改脚本的情况下工作,只需使模板如下:

class {{class_name}}({{base_class_name}}):
def __init__(self, {{ parameters|join(', ') }}):
{{comment}}
super().__init__()
{% for param in parameters%}
self.{{param}} = {{param}}
{%- endfor %}
self.parameters = [{% for param in parameters  %}self.{{ param }}{%- if not loop.last %}, {% endif %}{% endfor %}]

输出也稍微整洁一些。然后只需要一个模板变量(parameters(,就可以在模板本身中进行格式化。

class TestClass(BaseClass):
def __init__(self, param1, param2, param3):
"""My generated class"""
super().__init__()
self.param1 = param1
self.param2 = param2
self.param3 = param3
self.parameters = [self.param1, self.param2, self.param3]

您可以在列表中的模板中使用for循环:

[{% for param in parameter_list%} {{param}} {%- endfor %}]

如果你更改代码如下将工作

您的脚本

from itertools import product
from pathlib import Path
import jinja2
def create_class_from_template():
templates_path = '/home/lucas/capagile_codes/templates'
jinja_env = jinja2.Environment(loader=jinja2.FileSystemLoader(templates_path))
jinja_env.filters['product'] = product
parameters = ['param1', 'param2', 'param3']  
parameter_list = [f'self.{param},' for param in parameters[:-1]]  # modified line
parameter_list.append(f'self.{parameters[-1]}') # added line
template_variables = { 
'class_name': 'TestClass',
'base_class_name': 'BaseClass',
'comment': '"""My generated class"""',
'parameters': parameters,
'parameter_list': parameter_list
}
template = jinja_env.get_template('class_template.py.jinja2')
my_class = template.render(template_variables)
with open('my_new_class.py', 'w') as file:
file.write(my_class)

create_class_from_template()

你的jinja模板

class {{class_name}}({{base_class_name}}):

def __init__(self, {{ parameters|join(', ') }}):
{{comment}}
super().__init__()
{% for param in parameters%}
self.{{param}} = {{param}}
{%- endfor %}
self.parameters = [{% for param in parameter_list%} {{param}} {%- endfor %}]

结果文件

class TestClass(BaseClass):

def __init__(self, param1, param2, param3):
"""My generated class"""
super().__init__()

self.param1 = param1
self.param2 = param2
self.param3 = param3
self.parameters = [ self.param1, self.param2, self.param3]

最新更新