How to read the contents of a "Generator Object" from the load_all method for yaml file?

Asked

Viewed 90 times

1

I need to maintain a function that returns me a Generator Object from a yaml file. In another function I want to access the yaml file data.

import ruamel.yaml

def load():
    yaml = ruamel.yaml.YAML(typ='safe')
    with open('davros.yaml', 'r') as stream:
        yaml_config= yaml.load_all(stream)
    return yaml_config

def dictionary(doc):
    dicionario = list(doc)  # ?????? da erro aqui. É esse linha que preciso de ajuda
    print dicionario

doc = load()
dictionary(doc)

So I want to keep the function load and from the return of it I want to create a dictionary with the file data in another function, in this case the dictionary.

Erro: 
Traceback (most recent call last):
  File "C:/Users/jaqueline.prass/Documents/pessoais/teste/arq_ini_yaml/haha.py", line 14, in <module>
    dictionary(doc)
  File "C:/Users/jaqueline.prass/Documents/pessoais/teste/arq_ini_yaml/haha.py", line 10, in dictionary
    dicionario = list(doc)
  File "C:\Users\jaqueline.prass\Documents\pessoais\teste\arq_ini_yaml\venv\lib\site-packages\ruamel\yaml\main.py", line 362, in load_all
    while constructor.check_data():
  File "C:\Users\jaqueline.prass\Documents\pessoais\teste\arq_ini_yaml\venv\lib\site-packages\ruamel\yaml\constructor.py", line 98, in check_data
    return self.composer.check_node()
  File "_ruamel_yaml.pyx", line 687, in _ruamel_yaml.CParser.check_node
  File "_ruamel_yaml.pyx", line 902, in _ruamel_yaml.CParser._parse_next_event
  File "_ruamel_yaml.pyx", line 911, in _ruamel_yaml.input_handler
ValueError: I/O operation on closed file
  • yaml.load_all seems to iterate over several files in a directory; for your case should not be yaml.load?

  • Yes, with the load it already returns me a dictionary with the data of the file. But I needed a function that would return me an object, not to break a test that will be done later. I don’t know if it can be done.

  • And then you got the reading done?

  • I can read the data, but I couldn’t use the load function. So I need to change my entire test file, which is not what I wanted, but anyway, this is what we have

1 answer

1

Let’s focus on this part of the code, which is where the problem you’re facing is generated:

with open('davros.yaml', 'r') as stream:
    yaml_config= yaml.load_all(stream)
return yaml_config

When you use with ... as: to open a file, as soon as the iteration is over, the open file is closed and you can’t access it anymore. Like the yaml_config that you return is a generator object which depends on the open file, you will no longer be able to run it properly.

Then we have to add a line in the code to run the generator object and store it in an object while we are still with the open file, that is, still inside the with ... as:. Thus:

with open('davros.yaml', 'r') as stream:
    yaml_config=yaml.load_all(stream)
    yaml_list=[item for item in yaml_generator] # armazena enquanto está aberto
return yaml_list

This way, we will have the entire file stored in the list yaml_list and each position in the list will be a document from your yaml file, which you can use to do tests. With this, you will no longer need the function dictionary().

Browser other questions tagged

You are not signed in. Login or sign up in order to post.