Advanced Examples

Nested Records

If you have a heavily nested data set, you can nest data records to parse it out.

>>> from typing import List
>>> from data_records import datarecord

>>> @datarecord
... class Location:
...     latitude: float
...     longitude: float

>>> @datarecord
... class Address:
...     address: str
...     city: str
...     state: str
...     zipcode: int
...     location: Location

>>> @datarecord
... class Person:
...     name: str
...     age: int
...     addresses: List[Address] = []

>>> data = [
...     { 'name': 'Bob', 
...       'age': 30, 
...       'addresses': [
...         { 'address': '123 Any Street', 
...           'city': 'Anytown',
...           'state': 'ST',
...           'zipcode': 12345,
...           'location': { 'latitude': 12.34, 'longitude': 98.76 },
...         },
...         { 'address': '345 Any Street', 
...           'city': 'Anytown',
...           'state': 'ST',
...           'zipcode': 12345,
...           'location': { 'latitude': 45.67, 'longitude': 98.54 },
...         },
...       ],
...     },
...     {'name': 'John', 'age': 42, 'addresses': []},
... ]

>>> records = list(map(Person.from_dict, data))

>>> records[0].addresses[0].location.latitude
12.34

Safe Mutable Defaults

Some python veterans might be worried on declaring a property like bar: List[str] = [] will cause all instances of a class to share a reference like so:

>>> class Foo:
...     def __init__(self, bar = []):
...         self.bar = bar

>>> f1 = Foo()
>>> f2 = Foo()
>>> f1 is f2
False
>>> f1.bar.append('test')
>>> f2.bar
['test']

However the method used to coerce types performs a deep copy, derefencing the mutable default. So all copies of Foo will copy from the same mutable default, but none will have a direct reference to it.

>>> from typing import List
>>> from data_records import datarecord

>>> @datarecord
... class Foo:
...     bar: List[str] = []

>>> f1 = Foo()
>>> f2 = Foo()
>>> f1 is f2
False
>>> f1.bar.append('test')
>>> f2.bar
[]