Python Variables – Why Use namedtuple Over SimpleNamespace

dictionarypythonvariables

At one point or another you might come over functions with a lot of arguments. Sometimes it makes sense to combine some of the arguments into super-arguments. I've often done this with dicts, but now I'm looking at better ways of doing it.

I'd like to turn …

def do_something(ax, ay, az, bu, bv, c):
    # Do something

… into …

def do_something(a, b, c):
    # Do something

… where a and b contain their subvariations.

One way to do this is to do:

A = namedtuple('A', 'x, y, z')
a = A(ax, ay, az)
B = namedtuple('B', 'u, v')
b = B(bu, bv)

However, this seems simpler:

a = SimpleNamespace(x=ax, y=ay, z=az)
b = SimpleNamespace(u=bu, v=bv)

What is the drawback? The fact that a and b aren't well typed? They aren't A and B objects?

(Btw, don't worry about the variable names. I don't normally use as short variable names.)

Best Answer

SimpleNamespace is basically just a nice facade on top of a dictionary. It allows you to use properties instead of index keys. This is nice as it is super flexible and easy to manipulate.

The downside of that flexibility is that it doesn't provide any structure. There is nothing to stop someone from calling SimpleNamespace(x=ax, y=ay) (and del a.z at some point later). If this instance gets passed to your function, the exception occurs when you try to access the field.

In contrast, namedtuple lets you create a structured type. The type will have a name and it will know what fields it is supposed to have. You won't be able to make an instance without each of those field and they can't be removed later. Additionally, the instance is immutable, so you will know that the value in a.x will always be the same.

It's up to you to decide if you need the flexibility that SimpleNamespace gives you, or if you prefer to have the structure and guarantees provided by namedtuple.

Related Topic