mmfutils.containers

Provides convenience containers that support pickling and archiving.

Archiving is supported through the interface defined by the persist package (though use of that package is optional and it is not a dependency).

class mmfutils.containers.Object[source]

Bases: object

General base class with a few convenience methods.

Constructors: The __init__ method should simply be used to set variables, all initialization that computes attributes etc. should be done in init() which will be called at the end of __init__.

This aids pickling which will save only those variables defined when the base __init__ is finished, and will call init() upon unpickling, thereby allowing unpicklable objects to be used (in particular function instances).

Note

Do not use any of the following variables:

  • _empty_state: reserved for objects without any state

  • _independent_attributes, _dependent_attributes, initialized: Used to flag if attributes have been changed but without init() being called. (See below.)

By default setting any attribute in picklable_attributes will set the initialized flag to False. This will be set to True when init() is called. Objects can then include an assert self.initialized in the appropriate places.

To allow for some variables to be set without invalidating the object we also check the set of names _independent_attributes.

Note

This redefines __setattr__ to provide the behaviour.

Examples

>>> class A(Object):
...     def __init__(self, x=0):
...         self.x = x
...         Object.__init__(self)
...     def init(self):
...         self.x1 = self.x + 1   # A dependent variable
...         Object.init(self)
...     def check(self):
...         if not self.initialized:
...             raise AssertionError("Please call init()!")
...         return self.x1 == self.x + 1
>>> a = A(x=0)
>>> a.check()
True
>>> a.x = 2.0
>>> a.check()
Traceback (most recent call last):
...
AssertionError: Please call init()!
>>> a.init()
>>> a.check()
True
__setattr__(key, value)[source]

Sets the initialized flag to False if any picklable attribute is changed.

get_persistent_rep(env)[source]

Return (rep, args, imports).

Define a persistent representation rep of the instance self where the instance can be reconstructed from the string rep evaluated in the context of dict args with the specified imports = list of (module, iname, uiname) where one has either import module as uiname, from module import iname or from module import iname as uiname.

This satisfies the IArchivable interface for the persist package.

init()[source]

Define any computed attributes here.

Don’t forget to call Object.init()

initialized = False
picklable_attributes = ()
class mmfutils.containers.Container(*argv, **kw)[source]

Bases: mmfutils.containers.Object, collections.abc.Sized, collections.abc.Iterable, collections.abc.Container

Simple container object.

Attributes can be specified in the constructor. These will form the representation of the object as well as picking. Additional attributes can be assigned, but will not be pickled.

Examples

>>> c = Container(b='Hi', a=1)
>>> c                       # Note: items sorted for consistent repr
Container(a=1, b='Hi')
>>> c.a
1
>>> c.a = 2
>>> c.a
2
>>> tuple(c)                # Order is lexicographic
(2, 'Hi')
>>> c.x = 6                 # Will not be pickled: only for temp usage
>>> c.x
6
>>> 'a' in c
True
>>> 'x' in c
False
>>> import pickle
>>> c1 = pickle.loads(pickle.dumps(c))
>>> c1
Container(a=2, b='Hi')
>>> c1.x
Traceback (most recent call last):
...
AttributeError: 'Container' object has no attribute 'x'
class mmfutils.containers.ContainerList(*argv, **kw)[source]

Bases: mmfutils.containers.Container, collections.abc.Sequence

Simple container object that behaves like a list.

Examples

>>> c = ContainerList(b='Hi', a=1)
>>> c                       # Note: items sorted for consistent repr
ContainerList(a=1, b='Hi')
>>> c[0]
1
>>> c[0] = 2
>>> c.a
2
>>> tuple(c)                # Order is lexicographic
(2, 'Hi')
class mmfutils.containers.ContainerDict(*argv, **kw)[source]

Bases: mmfutils.containers.Container, collections.abc.MutableMapping

Simple container object that behaves like a dict.

Attributes can be specified in the constructor. These will form the representation of the object as well as picking. Additional attributes can be assigned, but will not be pickled.

Examples

>>> from collections import OrderedDict
>>> c = ContainerDict(b='Hi', a=1)
>>> c                       # Note: items sorted for consistent repr
ContainerDict(a=1, b='Hi')
>>> c['a']
1
>>> c['a'] = 2
>>> c.a
2
>>> OrderedDict(c)
OrderedDict([('a', 2), ('b', 'Hi')])