How to Convert YAML to List of Objects in Python
In this tutorial, you’ll learn how to convert YAML data into a list of Python objects using various methods.
We’ll cover simple conversions using dictionaries, using custom classes, handling nested structures, and dealing with cyclic references.
Custom Class for Object Creation
To convert YAML data into instances of a custom class, you can define a class and use a custom constructor with PyYAML
.
import yaml class Person: def __init__(self, name, age, city): self.name = name self.age = age self.city = city def person_constructor(loader, node): values = loader.construct_mapping(node) return Person(**values) class CustomLoader(yaml.SafeLoader): pass CustomLoader.add_constructor('!Person', person_constructor) yaml_data = """ - !Person name: Omar age: 28 city: Giza - !Person name: Mona age: 32 city: Luxor """ people = yaml.load(yaml_data, Loader=CustomLoader) for person in people: print(f"{person.name} is {person.age} years old and lives in {person.city}")
Output:
Omar is 28 years old and lives in Giza Mona is 32 years old and lives in Luxor
Each YAML item is loaded into a Person
object, and you print out their details.
Custom Class for Nested Objects
For YAML data with nested structures, you can create nested classes and adjust the constructor to handle them.
import yaml class Address: def __init__(self, city, street): self.city = city self.street = street class Person: def __init__(self, name, age, address): self.name = name self.age = age self.address = address def address_constructor(loader, node): values = loader.construct_mapping(node) return Address(**values) def person_constructor(loader, node): values = loader.construct_mapping(node) return Person(**values) class CustomLoader(yaml.SafeLoader): pass CustomLoader.add_constructor('!Person', person_constructor) CustomLoader.add_constructor('!Address', address_constructor) yaml_data = """ - !Person name: Salma age: 27 address: !Address city: Aswan street: Nile Avenue """ people = yaml.load(yaml_data, Loader=CustomLoader) person = people[0] print(f"{person.name} is {person.age} years old and lives on {person.address.street}, {person.address.city}")
Output:
Salma is 27 years old and lives on Nile Avenue, Aswan
The nested Address
object is properly constructed and associated with the Person
object.
Using YAMLObject
You can use yaml.YAMLObject to map YAML entries to Python objects without custom constructors.
import yaml yaml_data = """ !Person name: Karim age: 35 city: Hurghada """ class Person(yaml.YAMLObject): yaml_tag = '!Person' def __init__(self, name, age, city): self.name = name self.age = age self.city = city person = yaml.load(yaml_data, Loader=yaml.Loader) print(f"{person.name} is {person.age} years old and lives in {person.city}")
Output:
Karim is 35 years old and lives in Hurghada
Handle Cyclic References
When dealing with YAML data that has cyclic references, you can enable the resolver in PyYAML
to handle them.
import yaml yaml_data = """ a: &id001 name: Ali friend: *id001 """ data = yaml.safe_load(yaml_data) print(data['a']['friend']['name'])
Output:
Ali
The cyclic reference is resolved, and you can access the nested data without causing infinite recursion.
Mokhtar is the founder of LikeGeeks.com. He is a seasoned technologist and accomplished author, with expertise in Linux system administration and Python development. Since 2010, Mokhtar has built an impressive career, transitioning from system administration to Python development in 2015. His work spans large corporations to freelance clients around the globe. Alongside his technical work, Mokhtar has authored some insightful books in his field. Known for his innovative solutions, meticulous attention to detail, and high-quality work, Mokhtar continually seeks new challenges within the dynamic field of technology.