Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/backbone.js/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python Jinja2:格式+;加入列表中的项目_Python_Jinja2_Ansible - Fatal编程技术网

Python Jinja2:格式+;加入列表中的项目

Python Jinja2:格式+;加入列表中的项目,python,jinja2,ansible,Python,Jinja2,Ansible,play\u hosts是一个播放的所有机器的列表。我想用format()之类的东西重写它们,比如rabbitmq@%s,然后用join()之类的东西将它们连接在一起。因此: {{ play_hosts|format(???)|join(', ') }} 所有格式示例都使用管道,其中输入是格式字符串而不是列表。有没有办法用这些(或其他东西)来实现我想要的?输出应该类似于: ['rabbitmq@server1', 'rabbitmq@server2', rabbitmq@server3', .

play\u hosts
是一个播放的所有机器的列表。我想用
format()
之类的东西重写它们,比如
rabbitmq@%s
,然后用
join()
之类的东西将它们连接在一起。因此:

{{ play_hosts|format(???)|join(', ') }}
所有格式示例都使用管道,其中输入是格式字符串而不是列表。有没有办法用这些(或其他东西)来实现我想要的?输出应该类似于:

['rabbitmq@server1', 'rabbitmq@server2', rabbitmq@server3', ...]
[
{% set comma = joiner(",") %}    
{% for host in play_hosts %}
    {{ comma() }}
    {{ "rabbitmq@%s"|format(host) }}
{% endfor %}
]
jinja2文档描述的格式如下:

format(value, *args, **kwargs)
在对象上应用python字符串格式:

{{ "%s - %s"|format("Hello?", "Foo!") }}
-> Hello? - Foo!

因此,它给出了三种输入,但没有在示例中描述这些输入,示例中显示了一种在管道中,另两种通过args传入。是否有关键字arg来指定管道传输的字符串?请帮帮我,巨蟒僧侣

您可以创建自定义过滤器

# /usr/share/ansible/plugins/filter/format_list.py (check filter_plugins path in ansible.cfg)

def format_list(list_, pattern):
    return [pattern % s for s in list_]


class FilterModule(object):
    def filters(self):
        return {
            'format_list': format_list,
        }
并使用它

{{ play_hosts | format_list('rabbitmq@%s') }}

您不仅可以通过
加入
,还可以将前缀与之一起添加。现在,这不是一个非常复杂的python解决方案,而是一个非常简单的工作解决方案:

[rabbitmq@{{ play_hosts | join(', rabbitmq@') }}]

在ansible中,您可以使用正则表达式替换过滤器:

{{ play_hosts | map('regex_replace', '^(.*)$', 'rabbitmq@\\1') | list }}

我相信另一种方法是使用
joiner
全局函数,正如您在中所读到的:

joiner被传递一个字符串,并且在每次调用它时都会返回该字符串,但第一次调用时除外(在这种情况下,它返回一个空字符串)。你可以用它来连接东西

因此,您的代码类似于:

['rabbitmq@server1', 'rabbitmq@server2', rabbitmq@server3', ...]
[
{% set comma = joiner(",") %}    
{% for host in play_hosts %}
    {{ comma() }}
    {{ "rabbitmq@%s"|format(host) }}
{% endfor %}
]

这样行吗?(我从未使用过jinja)
{%for host in play_hosts%}
{code>{“rabbitmq@%s”| format(host)}}
{%endfor%}
似乎您只需要一个列表理解功能。@Jinja2不支持Barmar列表组件。我认为这是最好的解决方案。如果你试图在剧本中完成所有的工作,那么你的Jinja2代码将很快变得笨拙。这样的
格式列表
应该是Jinja2的一部分!重复并不好,但看起来比
regex\u replace
更干净。真的缺少一个干净的过滤器+1但是,对于解决方法,如果列表为空,这将留下一个悬空的
rabbitmq@
。简化:
{{play_hosts | map('regex_replace','^',rabbitmq@')| list}