dictable_namedtuple

privex.helpers.collections.dictable_namedtuple(typename, field_names, *args, **kwargs) → Union[Type[collections.namedtuple], dict][source]

Creates a dictable_namedtuple type for instantiation (same usage as collections.namedtuple()) - unlike namedtuple, dictable_namedtuple instances allow item (dict-like) field access, support writing and can be painlessly converted into dictionaries via dict(my_namedtuple).

Named tuple instances created from dictable_namedtuple types are generally backwards compatible with any code that expects a standard collections.namedtuple() type instance.

Quickstart

>>> from privex.helpers import dictable_namedtuple
>>> # Define a dictable_namedtuple type of 'Person', which has two fields - first_name and last_name
>>> p = dictable_namedtuple('Person', 'first_name last_name')
>>> john = p('John', 'Doe')    # Alternatively you can do p(first_name='John', last_name='Doe')
>>> john.first_name            # You can retrieve keys either via attributes (dot notation)
'John'
>>> john['last_name']          # Via named keys (square brackets)
'Doe'
>>> john[1]                    # Or, via indexed keys (square brackets, with integer keys)
'Doe'
>>> john.middle_name = 'Davis' # You can also update / set new keys via attribute/key/index
>>> dict(john)                 # Newly created keys will show up as normal in dict(your_object)
{'first_name': 'John', 'last_name': 'Doe', 'middle_name': 'Davis'}
>>> john                       # As well as in the representation in the REPL or when str() is called.
Person(first_name='John', last_name='Doe', middle_name='Davis')

This function adds / overrides the following methods on the generated namedtuple type:

  • _asdict

  • __iter__

  • __getitem__

  • __getattribute__

  • __setitem__

  • __setattr__

  • __repr__

Extra functionality compared to the standard namedtuple() generated classes:

  • Can access fields via item/key: john['first_name']

  • Can convert instance into a dict simply by casting: dict(john)

  • Can set new items/attributes on an instance, even if they weren’t previously defined. john['middle_name'] = 'Davis' or john.middle_name = 'Davis'

Example Usage

First we’ll create a named tuple typle called Person, which takes two arguments, first_name and last_name.

>>> from privex.helpers import dictable_namedtuple
>>> Person = dictable_namedtuple('Person', 'first_name last_name')

Now we’ll create an instance of Person called john. These instances look like normal namedtuple’s, and should be generally compatible with any functions/methods which deal with named tuple’s.

>>> john = Person('John', 'Doe')   # Alternatively you can do Person(first_name='John', last_name='Doe')
>>> john
Person(first_name='John', last_name='Doe')

Unlike a normal namedtuple type instance, we can access fields by attribute (.first_name), index ([0]), AND by item/key name (['last_name']).

>>> john.first_name
'John'
>>> john[0]
'John'
>>> john['last_name']
'Doe'

Another potentially useful feature, is that you can also update / create new fields, via your preferred method of field notation (other than numbered indexes, since those don’t include a field name):

>>> john['middle_name'] = 'Davis'
>>> john.middle_name = 'Davis'

We can also convert john into a standard dictionary, with a simple dict(john) cast. You can see that the new field we added (middle_name) is present in the dictionary serialized format.

>>> dict(john)
{'first_name': 'John', 'last_name': 'Doe', 'middle_name': 'Davis'}
Parameters
  • typename (str) – The name used for the namedtuple type/class

  • field_names (str) – One or more field names separated by spaces, e.g. 'id first_name last_name address'

Key bool read_only

(Default: False) If set to True, the outputted dictable_namedtuple instance will not allow new fields to be created via attribute / item setting.

Return Type[namedtuple] dict_namedtuple

A dict_namedtuple type/class which can be instantiated with the given field_names via positional or keyword args.