What is the difference between SimpleNamespace and empty class definition?
The following seems to work either way. What is the advantage (other than the nice repr
) of using types.SimpleNamespace
? Or is it the same thing?
>>> import types
>>> class Cls():
... pass
...
>>> foo = types.SimpleNamespace() # or foo = Cls()
>>> foo.bar = 42
>>> foo.bar
42
>>> del foo.bar
>>> foo.bar
AttributeError: 'types.SimpleNamespace' object has no attribute 'bar'
This is explained pretty well in the types module description. It shows you that types.SimpleNamespace
is roughly equivalent to this:
class SimpleNamespace:
def __init__(self, **kwargs):
self.__dict__.update(kwargs)
def __repr__(self):
keys = sorted(self.__dict__)
items = ("{}={!r}".format(k, self.__dict__[k]) for k in keys)
return "{}({})".format(type(self).__name__, ", ".join(items))
def __eq__(self, other):
return self.__dict__ == other.__dict__
This provides the following advantages over an empty class:
- It allows you to initialize attributes while constructing the object:
sn = SimpleNamespace(a=1, b=2)
- It provides a readable
repr()
:eval(repr(sn)) == sn
- It overrides the default comparison. Instead of comparing by
id()
, it compares attribute values instead.
A class types.SimpleNamespace
provides a mechanism to instantiate an object that can hold attributes and nothing else. It is, in effect, an empty class with a fancier __init__()
and a helpful __repr__()
:
>>> from types import SimpleNamespace
>>> sn = SimpleNamespace(x = 1, y = 2)
>>> sn
namespace(x=1, y=2)
>>> sn.z = 'foo'
>>> del(sn.x)
>>> sn
namespace(y=2, z='foo')
or
from types import SimpleNamespace
sn = SimpleNamespace(x = 1, y = 2)
print(sn)
sn.z = 'foo'
del(sn.x)
print(sn)
output:
namespace(x=1, y=2)
namespace(y=2, z='foo')
This answer may also be helpful.