Tutorial 1 - Using a Simple Serialised Object

The simplest use of anamnesis allows the serialisation of classes to and from hdf5 with relatively little extra code.

In order to both reading to and writing from HDF5 files to work, there are four basic steps

  1. Inherit from the anamnesis.AbstractAnam class and call the class constructor
  2. Ensure that your class constructor (__init__) can be called with no arguments (you may pass arguments to it but they must have default values)
  3. Call the anamnesis.register_class function with the class
  4. Populate the hdf5_outputs class variable with a list of member variable names necessary for serialisation/de-serialisation

Note that anamnesis uses the fully qualified class name when autoloading during the unserialising (loading) of object. If you want to use locally defined classes, you will have to ensure that they have been manually imported. For our examples, we will place our classes in the files test_classesX.py (where X is an ineger) and ensure that we can import this file into Python (i.e. it is on the PYTHONPATH or in the current working directory).

Our first example class is going to be a simple model of a person’s name and age. We place the following code in test_classes1.py

#!/usr/bin/python3

from anamnesis import AbstractAnam, register_class


class SimplePerson(AbstractAnam):

    hdf5_outputs = ['name', 'age']

    def __init__(self, name='Unknown', age=0):
        AbstractAnam.__init__(self)

        self.name = name
        self.age = age


register_class(SimplePerson)

If we examine the person group in the HDF5 file, we can see that the class member variables:

../_images/test_classes1.png

We can now write a script which will serial our data into an HDF5 file. We specify the group name when writing out.

#!/usr/bin/python3

import h5py

from test_classes1 import SimplePerson

# Create a person
s = SimplePerson('Fred', 42)

print(s.name)
print(s.age)

# Serialise the person to disk
f = h5py.File('test_script1.hdf5', 'w')
s.to_hdf5(f.create_group('person'))
f.close()

And write another script which loads the class back in. Because this class is not registered, we need to make sure that we have imported the module first. First of all, we can load from the file; if we know there is only one group in the file, we do not even need to specify the group name:

#!/usr/bin/python3

from anamnesis import obj_from_hdf5file

import test_classes1  # noqa: F401

# Load the class from the HDF5 file
s = obj_from_hdf5file('test_script1.hdf5')

# Show that we have reconstructed the object
print(type(s))
print(s.name)
print(s.age)


# Demonstrate how to specifically choose which group to load
s2 = obj_from_hdf5file('test_script1.hdf5', 'person')

# Show that we have reconstructed the object
print(type(s))
print(s.name)
print(s.age)

If we want to load multiple objects from the same HDF5 file, we can open the file once and then use a function which loads from the group of the opened file. We can also tell anamnesis that it should autoload modules which start with a certain name. Both of these possibilities are demonstrated in the script test_script1_read_B.py:

#!/usr/bin/python3

import h5py

from anamnesis import obj_from_hdf5group, ClassRegister

# Register our class prefix so that we autoload our objects.  This
# allows loading all classes whose fully resolved name
# starts with test_classes1; e.g. test_classes1.SimplePerson
ClassRegister().add_permitted_prefix('test_classes1')

# Open our HDF5 file
f = h5py.File('test_script1.hdf5', 'r')

# Load the class from the HDF5 file using our
# obj_from_hdf5group method
s = obj_from_hdf5group(f['person'])

# Show that we have reconstructed the object
print(type(s))
print(s.name)
print(s.age)

# Close our HDF5 file
f.close()