Skip to main content

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


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

mutabletuple-0.2.tar.gz (6.9 kB view hashes)

Uploaded Source

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page