使用Python和YAML

时间:2016-05-10 09:25:44

标签: python file yaml pyyaml

我有一个YAML文件,我想存储不同的"玩家"在我的游戏中。

YAML文件如下所示:

Person:
  Name:
  Age:
  Nationality:
  Footed:
  Position:

创建播放器后,YAML文件应如下所示:

Person:
   Name: Rich
   Age: 23 
   Nationality: British
   Footed: Right
   Position: Forward

到目前为止,我的代码是这样的:

import yaml

name = input('What is your name? ')
age = int(input('What is your age? '))
nationality = input('What is your nationality? ')
footed = input('What foot? ')
position = input('What is your position? ')

with open('test.yml', 'a') as outfile:
    outfile.write(yaml.dump({'Name' : name, 'Age' : age, 'Nationality' : nationality,
    'Footed' : footed, 'Position' : position}))

但是当我运行它并给用户输入时,yaml文件最终看起来像:

{Age: 2, Footed: r, Name: r, Nationality: r, Position: r}

如何将其添加到YAML文件而不是追加,以及如何将其垂直构建而不是水平构建?最后,如果我想添加10/20 / n的玩家数量,我希望YAML文件将它们全部存储在彼此之下,这样我就可以单独调用每个玩家

3 个答案:

答案 0 :(得分:1)

当您按原样写出YAML时,首先将数据结构写入内存中的文件,然后将内存文件内容作为字符串检索,然后将其写入文件。这是低效和缓慢的。

您还应该阅读您拥有的YAML文件,更新数据结构并将其转储:

import yaml

file_name = 'test.yml'

with open(file_name) as infile:
    data = yaml.load(infile)

person = data['Person']
person['name'] = input('What is your name? ')
person['age'] = int(input('What is your age? '))
person['nationality'] = input('What is your nationality? ')
person['footed'] = input('What foot? ')
person['position'] = input('What is your position? ')

with open(file_name, 'w') as outfile:
    yaml.dump(data, stream=outfile, default_flow_style=False, indent=3)

default_flow_style参数可确保您的键值对列在彼此之下。

使用PyYAML,infile中的任何注释都将丢失,映射中键的顺序可能会被扰乱。如果这是一个问题,我建议您使用ruamel.yaml包(免责声明:我是该包的作者),并将代码更改为:

import ruamel.yaml

file_name = 'test.yml'

with open(file_name) as infile:
    data = ruamel.yaml.round_trip_load(infile)

person = data['Person']
person['name'] = input('What is your name? ')
person['age'] = int(input('What is your age? '))
person['nationality'] = input('What is your nationality? ')
person['footed'] = input('What foot? ')
person['position'] = input('What is your position? ')

with open(file_name, 'w') as outfile:
    yaml.round_trip_dump(data, stream=outfile, indent=3)

如果您想存储多个玩家。确保您的顶层数据结构是一个序列,或者是从某个唯一值(例如Person的名称)映射。在这种情况下,使用不同的输入文件作为模板,并通过读取输入文件来更新输出文件,附加到列表cq。更新dict并写出文件。只要名称是唯一的,使用顶级映射/字典就可以更容易地完成此操作。

答案 1 :(得分:0)

  • 使用"w"打开文件,而不是"a"
  • 您还必须撰写Person
  • 使用选项default_flow_style=False

代码:

with open('test.yml', 'w') as outfile:
    outfile.write(yaml.dump(
      {"Person": {
        'Name' : name,
        'Age' : age,
        'Nationality' : nationality,
        'Footed' : footed,
        'Position' : position}
      },
      default_flow_style=False))

输出

Person:
   Name: Rich
   Age: 23 
   Nationality: British
   Footed: Right
   Position: Forward

答案 2 :(得分:0)

你可以这样做:

import pyaml as yaml

name = input('What is your name? ')
age = int(input('What is your age? '))
nationality = input('What is your nationality? ')
footed = input('What foot? ')
position = input('What is your position? ')

person = {'Person':{
              'Name': name, 
              'Age': age, 
              'Nationality': nationality, 
              'Footed': footed, 
              'Position': position}
         }

with open('test.yml', 'a') as outfile:
    yaml.dump(person, outfile, indent=4)