Tengo un archivo YAML donde quiero almacenar diferentes "jugadores" en mi juego.

El archivo YAML se ve así:

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

Después de haber creado un reproductor, el archivo YAML debería verse así:

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

Hasta ahora mi código es así:

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}))

Pero cuando ejecuto esto y le doy al usuario la entrada, el archivo yaml termina luciendo así:

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

¿Cómo consigo que se agregue al archivo YAML en lugar de agregarlo y también cómo lo estructuro verticalmente en lugar de horizontalmente? Finalmente, si deseo agregar 10/20 / n número de jugadores, me gustaría que el archivo YAML los almacene uno debajo del otro para poder llamar a cada uno individualmente

1
NewUser123 10 may. 2016 a las 12:25

3 respuestas

La mejor respuesta

Cuando escribe su YAML como lo hace, primero escribe la estructura de datos en un archivo en la memoria, luego recupera el contenido del archivo de memoria como una cadena y luego lo escribe en un archivo. Eso es ineficiente y lento.

También debe leer el archivo YAML que tiene, actualizar la estructura de datos y volcarlo:

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)

El parámetro default_flow_style asegura que sus pares clave-valor se enumeren uno debajo del otro.

Con PyYAML, cualquier comentario en el archivo se perderá y el orden de las teclas en el mapeo probablemente se codificará. Si eso es un problema, le recomiendo que use el paquete ruamel.yaml (descargo de responsabilidad: soy el autor de ese paquete) y cambie el código a:

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)

Si quieres almacenar múltiples jugadores. Asegúrese de que su estructura de datos de nivel superior sea una secuencia o se asigne desde un valor único (por ejemplo, el nombre de la Persona). En ese caso, use un archivo de entrada diferente como plantilla y actualice el archivo de salida leyéndolo, agregando a la lista cq. actualizando el dict y escribiendo el archivo. Mientras los nombres sean únicos, es más fácil hacer esto con un mapeo / dict de nivel superior.

1
Anthon 11 may. 2016 a las 12:32
  • Abra el archivo usando "w", no "a".
  • También debe escribir un Person.
  • Use la opción default_flow_style=False.

Código:

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))

Salida

Person:
   Name: Rich
   Age: 23 
   Nationality: British
   Footed: Right
   Position: Forward
0
user5547025user5547025 10 may. 2016 a las 09:35

Puedes hacer lo siguiente:

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)
0
Orelus 10 may. 2016 a las 09:36