Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/281.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 PyYAML在不同的操作系统中表现不同_Python_Pyyaml - Fatal编程技术网

Python PyYAML在不同的操作系统中表现不同

Python PyYAML在不同的操作系统中表现不同,python,pyyaml,Python,Pyyaml,我现在有点被Pyaml搞糊涂了。我在我的Windows和Linux系统上安装了3.12版,并且看到它在对值进行排序时的行为有所不同 让我们看一下这个示例YAML文件: functions: function_a: value_1: 1 value_2: 1 value_3: 1 function_c: value_1: 1 value_2: 1 value_3: 1 funct

我现在有点被Pyaml搞糊涂了。我在我的Windows和Linux系统上安装了3.12版,并且看到它在对值进行排序时的行为有所不同

让我们看一下这个示例YAML文件:

functions:
    function_a:
        value_1: 1
        value_2: 1
        value_3: 1
    function_c:
        value_1: 1
        value_2: 1
        value_3: 1
    function_d:
        value_1: 1
        value_2: 1
        value_4: 1
    function_b:
        value_1: 1
        value_2: 1
        value_3: 1
像往常一样,通过conf=YAML.loadfp加载YAML文件

现在,这两个系统之间真正奇怪的是,当我尝试遍历所有函数时,两个操作系统的顺序都不同

在Windows上,它将是:

import yaml
with open('myyamlfile.yml') as fp:
    conf = yaml.load(fp)
for function in conf['functions']:
    print(function)

function_a
function_c
function_d
function_b
在Linux上,它是按顺序提供的:

import yaml
with open('myyamlfile.yml') as fp:
    conf = yaml.load(fp)
for function in conf['functions']:
    print(function)

function_a
function_b
function_c
function_d
我真的不知道为什么。我在两台具有相同模块版本的机器上使用相同的代码。这两台机器之间唯一的区别是操作系统和事实,在Windows上我使用3.6.5,在Linux上我使用3.4.8


有人能告诉我为什么会发生这种情况吗?

首先是YAML规范,PyYAML所基于的旧1.1规范和新的1.2规范2009都表明映射键是无序的。因此,你不应该依赖订单在装货后到达那里

当然,在CPython的实现中有一个区别,在其他的实现中,它是从3.7开始的,而Python 3.6之前的dict是不排序的。PyYAML创建一个dict并按照从YAML文档中读取密钥的顺序填充它,因此3.6.5版本获得了密钥插入的顺序,而3.4.8则没有

如果您需要两个版本的行为相同,我建议您显式地对键进行排序:

for function in sort(conf['functions']):
如果您真的需要按照密钥在YAML文档中的顺序获取密钥,我建议您查看免责声明:我是YAML 1.2兼容包的作者,并且确实如此。e、 g:

import pathlib
import ruamel.yaml

yaml = ruamel.yaml.YAML()
file_name = pathlib.Path('myfile.yaml')
conf = yaml.load(file_name)
for function in conf['functions']:
    print(function)

这将获得Python2.7到3.7中的输出,就像在Python3.6.5中一样。在ruamel.yaml中,默认情况下执行yaml.load是安全的。

您应该使用yaml.safe\u load,因为yaml.load是不必要的,而B被证明是不安全的。非常好的提示,谢谢!嗨,好吧,实际上是你描述的另一种方式。在3.6.5版本的Windows机器上,dict是无序的,而在3.4.8版本的Linux上,dict是无任何特定原因排序的。这就是为什么我想知道。我想要实现的是,函数下的标记的写入顺序应该保持不变。但是我现在解决了我的问题,添加了一个runorder,并将函数添加到一个字典中,使用runorder值作为键,这样就可以保持我想要的顺序。我认为排序与词汇排序之间存在一些混淆。您在3.6+中的排序是我在ruamel.orderedict文档中所称的插入排序,而不是排序排序。因此,放入dict中且未删除的第一个键是迭代时作为第一个键得到的,等等。如果YAML文件中的顺序是您想要的,那么ruamel.YAML将解决您的问题。有一个明确的键列表也可以。或者,制作一系列单键值项,例如通过转储显式OrderedICT来完成