Similar to namedlist, but with additional features (nested class, recursive merge, etc).
Project description
Overview
Similar to namedlist, but with additional features: * Print like a native python dictionary * Improve support for nested mutabletuple * Conversion to dictionary is done recursively * Can iterate using iteritems like dictionary * Merge nested mutable tuple from dict or other mutabletuple * MtFactory support arguments * Nested pickle support
Warning Pickling works, but only for mutabletuple with default values.
Typical usage
You can use mutabletuple like a mutable namedtuple:
>>> from mutabletuple import mutabletuple >>> from collections import OrderedDict >>> Point = mutabletuple('Point', 'x y') >>> p = Point(1, 3) >>> p.x = 2 >>> assert p.x == 2 >>> assert p.y == 3
Or, you can specify a default value for all fields:
>>> Point = mutabletuple('Point', ['x', 'y'], default=3) >>> p = Point(y=2) >>> assert p.x == 3 >>> assert p.y == 2
Or, you can specify per-field default values:
>>> Point = mutabletuple('Point', [('x', 0), ('y', 100)]) >>> p = Point() >>> assert p.x == 0 >>> assert p.y == 100
If you use a mapping, the value MtNoDefault is convenient to specify that a field uses the default value:
>>> from mutabletuple import MtNoDefault >>> Point = mutabletuple('Point', OrderedDict((('y', MtNoDefault), ... ('x', 100))), ... default=5) >>> p = Point() >>> assert p.x == 100 >>> assert p.y == 5
Namedlist-like behavior
A mutabletuple behaves almost like a namedlist. Check the documentation of namedlist for more details: https://pypi.python.org/pypi/namedlist
Additional features
Additional class members
mutabletuple class contain these members:
_asdict(): Returns a dict which maps field names to their corresponding values.
_fields: Tuple of strings listing the field names. Useful for introspection.
merge: Recursively merge with a dict or another mutabletuple.
orderedDict: Recursively convert a mutabletuple into an ordered dict.
iteritems: To iterate like a dict.
Mutable default values
For mutabletuple, be aware of specifying mutable default values. Due to the way Python handles default values, each instance of a mutabletuple will share the default. This is especially problematic with default values that are lists. For example:
>>> A = mutabletuple('A', [('x', [])]) >>> a = A() >>> a.x.append(4) >>> b = A() >>> assert b.x == [4]
This is probably not the desired behavior, so see the next section.
Specifying a factory function for default values
For mutabletuple, you can supply a zero-argument callable for a default, by wrapping it in a MtFactory call. The only change in this example is to change the default from [] to MtFactory(list). But note that b.x is a new list object, not shared with a.x:
>>> from mutabletuple import MtFactory >>> A = mutabletuple('A', [('x', MtFactory(list))]) >>> a = A() >>> a.x.append(4) >>> b = A() >>> assert b.x == []
Every time a new instance is created, your callable (in this case, list), will be called to produce a new instance for the default value.
Specifying arguments to a factory function
When using nested mutabletuple, you might want to provide arguments for the creation of nested mutabletuple. Here is an example of how to do it:
>>> Point = mutabletuple('Point', [('x', 0), ('y', 0)]) >>> Vector = mutabletuple('Vector', [('p1', MtFactory(Point, 2)), ... ('p2', MtFactory(Point, 4, 8))]) >>> v1 = Vector() >>> assert(v1 == Vector(Point(2, 0), Point(4, 8)))
Initialized points are created every time a vector is created.
Merging mutabletuple with mutabletuple or dict
When working with nested mutabletuple, it might be useful to be able to merge recursively with a dictionary that represents only a subset of the mutabletuple:
>>> Point = mutabletuple('Point', [('x', 0), ('y', 0)]) >>> Vector = mutabletuple('Vector', [('p1', MtFactory(Point)), ... ('p2', MtFactory(Point))]) >>> Shape = mutabletuple('Shape', [('v1', MtFactory(Vector)), ... ('v2', MtFactory(Vector))]) >>> s = Shape() >>> d = {'v1': {'p1': {'x': 20}, 'p2': Point(30, 40)}} >>> s.merge(d) >>> assert(s._asdict() == { ... 'v1': {'p1': {'x': 20, 'y': 0}, 'p2': {'x': 30, 'y': 40}}, ... 'v2': {'p1': {'x': 0, 'y': 0}, 'p2': {'x': 0, 'y': 0}}})
Iterating over instances
Because instances are iterable (like lists or tuples), iteration works the same way. Values are returned in definition order:
>>> Point = mutabletuple('Point', 'x y z t') >>> p = Point(1.0, 42.0, 3.14, 2.71828) >>> for value in p: ... print(value) 1.0 42.0 3.14 2.71828
Creating and using instances
Because the type returned by mutabletuple is a normal Python class, you create instances as you would with any Python class.
Change log
0.1 2015-03-21 Nicolas Bessou
Initial release.
Brings some additional features to a namedlist in order to support nested mutabletuple and recursive merge of the class.
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.