Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PyYaml.load_all() returns generator rather than a dict?

I am working with Yaml (and Python!) for the first time. I am attempting to load multiple documents from within a single .yaml file, but not getting a result that I would expect. I am expecting a dict of dicts back containing each of the documents, but am instead getting a generator object...? I should note that when I used yaml.load() in a previous test (instead of load_all()) on a single document yaml file, I was able to get a dictionary back just fine.

What obvious thing am I missing that is preventing me from receiving multiple docs back?

The test yaml:

---
Tiles:
 dungeon_floor:
   name: 'Dungeon Floor'
   blocked: False
   block_sight: False
   terrain_type: CONST.E_TERRAIN_TYPES.FLAT_FLOOR
   persistent_effects: 'None'
...
---
NPCs:
 gnoll:
   name: "Gnoll"
   equipment: Sword, Shield

def yaml_loader(filepath):
    """Load a yaml file."""
    with open(filepath, "r") as file_descriptor:
        data = yaml.load_all(file_descriptor)
    return data

And the code attempting to load and print the dict:

def yaml_loader(filepath):
    """Load a yaml file."""
    with open(filepath, "r") as file_descriptor:
        data = yaml.load_all(file_descriptor)
    return data

if __name__ == "__main__":
    filepath = CONST.YAML_ECS_CONFIG_PATH
    data = yaml_loader(filepath)
    print(data)

...produces the following terminal output:

<generator object load_all at 0x0000000003A64990>

Process finished with exit code 0
like image 357
originalMagoo Avatar asked Mar 15 '17 05:03

originalMagoo


1 Answers

Well, looking at the load_all implementation makes it obvious why this happens:

def load_all(stream, Loader=Loader):
    """
    Parse all YAML documents in a stream
    and produce corresponding Python objects.
    """
    loader = Loader(stream)
    try:
        while loader.check_data():
            yield loader.get_data()
    finally:
        loader.dispose()

It is indeed a generator. So you simply need to convert it to a list:

 data = list(yaml.load_all(file_descriptor))
like image 139
flyx Avatar answered Sep 19 '22 07:09

flyx