The second solution does not work:
>>> o = object()
>>> o.x = 10
AttributeError: 'object' object has no attribute 'x'
This is because instances of object do not have a __dict__
.
I agree that using square brackets to access attributes is not elegant. To return a value object, my team uses this (this code can certainly be improved):
class Struct(object):
"""
An object whose attributes are initialized from an optional positional
argument or from a set of keyword arguments (the constructor accepts the
same arguments than the dict constructor).
"""
def __init__(self, *args, **kwargs):
self.__dict__.update(*args, **kwargs)
def __repr__(self):
klass = self.__class__
attributes = ', '.join('{0}={1!r}'.format(k, v) for k, v in self.__dict__.iteritems())
return '{0}.{1}({2})'.format(klass.__module__, klass.__name__, attributes)
Using Struct
, your example can be rewritten as is:
def func():
return Struct(x = 10, y = 20)
The advantage of Struct
over namedtuple
is that you do not have to define your types beforehand. It is closer of what you use in a language like JavaScript for example. namedtuple
has the advantage to be more efficient and attributes are accessible by index or names at the same time.