Different python objects for dot notation lovers 
Tags: python, codequality
Published: 2020-03-02 19:21:19

# Why would I want to be able to use dot notation?

For years I've been using dictionaries to store all kind of things, especially when I needed to generate report on large amount of data.
Recently I was working on developing a rest api at work and I wanted to be able to store small pieces of flat data and access them  using dot notation as I find it more elegant and convenient than using the old *['key']* of a dictionary.
My criterias were the following:
- I didn't want to "hack" any data type by modifying their behaviors.
- I only want to use the standard library.

---

#Solutions:

* [SimpleNamespace](#SimpleNamespace) (3.3+)

* [namedtuple](#namedtuple) (2.6+)

* [enum](#enum) (3.4+)

* [dataclass](#dataclass) (3.7+)

---

#Examples

**SimpleNamespace** <a name="SimpleNamespace"></a>:

It allows you to instantiate an object immediately with any attributes that you like and create/modify them as necessary (it is a subclass of Object):

```python
from types import SimpleNamespace

dummy_object = SimpleNamespace()
#Creation of attributes
dummy_object.name = 'dummy_name'
dummy_object.age = 36
#Update of name attribute
dummy_object.name = 'dummy_name_test'
#Delete the name attribute
del dummy_object.name
```

**namedtuple** <a name="namedtuple"></a>:

As stated by its name it allows you to create a tuple and access its data by name rather than index.
As for a tuple, you can't modify it.

```python
from collections import namedtuple

person = namedtuple('Person', ['name', 'age'])
dummy_object = person('dummy_name', 36)
```

**Enum** <a name="enum"></a>:

An enum is a class where the attributes name are bound to constant values.
Attributes and values can't be modified.

```python
from enum import Enum

class dummy_object(Enum):
    name = 'dummy_name'
    age = 36
```

---

**dataclass** <a name="dataclass"></a>:

It's just a simple decorator that add special methods to classes (such as `__init__` and `__repr__`).
As for SimpleNamespace you can modify attributes and values.



```python
from dataclasses import dataclass

#You can add attributes without default value with type hinting.
@dataclass
class Person:
    name: str
    age: int
dummy_person = Person()

#You can add attributes with default value like with regular class.
@dataclass
class Person:
    name = 'dummy_name'
    age = 36
dummy_person = Person()
```

---

As a summary here is a quick table to understand the behavior of each kind of object.

 | SimpleNamespace | namedtupled | Enum | dataclass
--- | --- | --- | --- | ---
Instantiation |  Yes | Yes | No | Yes
Attribute mutability | Yes | No | No | Yes
Value mutability | Yes | No | No | Yes
Identity compare | Values | Values | ID | ID

Obviously you can always use regular classes or dictionnary but these objects might simplify your workflow and improve the readability of your code.

---
**References**
https://docs.python.org/3/library/types.html#types.SimpleNamespace
https://docs.python.org/3/library/collections.html#collections.namedtuple
https://docs.python.org/3/library/enum.html
https://docs.python.org/3/library/dataclasses.html