通过 set_fact 分配的一些浮点数被转换为字符串

some float assigned via set_fact is converted to string

我迷路了。使用 ansible-2.9.9-1.fc30.noarch 我不明白为什么这个 somedata.aaa 被 Ansible 转换为字符串:

- hosts: localhost
  remote_user: root
  gather_facts: no
  vars:
    aaa:
      - 1.111
      - 2.222
      - 3.333
    bbb: 4.444
  roles:
  tasks:
    - set_fact:
        somedata:
          aaa: "{{ aaa | max | float }}"
          bbb: "{{ bbb }}"
    - debug:
        msg: "orig: {{ aaa | max | type_debug }}   aaa: {{ somedata.aaa | type_debug }}   bbb: {{ somedata.bbb | type_debug }}"
    - debug:
        var: somedata
    - debug:
         msg: "{{ somedata | to_nice_json }}"

这是输出:

TASK [debug] ******************************************************************
Monday 08 June 2020  17:06:32 +0200 (0:00:00.350)       0:00:00.376 *********** 
ok: [localhost] => {
    "msg": "orig: float   aaa: str   bbb: float"
}

TASK [debug] ******************************************************************
Monday 08 June 2020  17:06:33 +0200 (0:00:00.332)       0:00:00.708 *********** 
ok: [localhost] => {
    "somedata": {
        "aaa": "3.333",
        "bbb": 4.444
    }
}

TASK [debug] ******************************************************************
Monday 08 June 2020  17:06:33 +0200 (0:00:00.318)       0:00:01.027 *********** 
ok: [localhost] => {
    "msg": "{\n    \"aaa\": \"3.333\",\n    \"bbb\": 4.444\n}"
}

为什么 somedata.aaa string 而不是 float?如何使它 浮动?

max 和 float 是 jinja 操作,默认情况下 jinja 总是 return 一个字符串。请注意 float 是在内部转换数字,jinja 然后将其放入字符串中。

3.333改成3就可以看到了:

aaa:
  - 1.111
  - 2.222
  - 3

使用您的代码,它会转换为 3.0 - 浮点值:

"somedata": {
        "aaa": "3.0",
        "bbb": 4.444
}

您可以通过将 jinja2_native = True 添加到 ansible.cfg 的默认部分来强制 jinja 总是 return 本机类型。代码现在应该 return 您所期望的:

TASK [debug] *************************
    "somedata": {
        "aaa": 3.333,
        "bbb": 4.444
    }
}

TASK [debug] *************************
    "msg": "{\n    \"aaa\": 3.333,\n    \"bbb\": 4.444\n}"
}

请记住,这可能会影响您代码的其他部分。