I often have to create a result object instance to return complex values from functions and wonder what's a nice Pythonic approach.
I am aware of the closely related attribute-assignment-to-built-in-object, but it is asking why he needs to hack a subclass workaround to use 'object'. I understand why already. I am asking instead if there is existing support in the standard library to avoid using 'object' and the subclass hack, either through an existing class or function.
What's the lightest, most Pythonic way to instantiate an instance that supports attribute assignment?
I am OK to be pointed right back to subclassing 'object' answer. It's really no big deal - just want to know if I had missed a cleaner approach supported by the standard library or builtins.
Sample of what I am trying to do:
try:
returnval = object()
returnval.foo = 1
returnval.bar = 2
print "\n\nSuccess with %s" % (returnval), vars(returnval), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
except Exception, e:
print "\n\nFailure with %s:%s" % (returnval, e), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
This fails, as expected, with
Failure with <object object at 0x102c520a0>:'object' object has no attribute 'foo' has __slots__: False has __dict__: False
I am not surprised. 'object' is a bare stub, and does not allow attribute assignment because it has no __dict__.
Instead I have to declare a placeholder class. Is there a cleaner way?
try:
class Dummy(object): pass
returnval = Dummy()
returnval.foo = 1
returnval.bar = 2
print "\n\nSuccess with %s" % (returnval), vars(returnval), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
except Exception, e:
print "\n\nFailure with %s:%s" % (returnval, e), "has __slots__:", hasattr(returnval, "__slots__"), "has __dict__:", hasattr(returnval, "__dict__")
This gives:
Success with <__main__.Dummy object at 0x102d5f810> {'foo': 1, 'bar': 2} has __slots__: False has __dict__: True
Using the Dummy/MyClass approach avoids these problems, but it gives off a mild code smell to litter my modules with Dummy classes.
Things that would not work/are not satisfactory:
Dictionaries. I would avoid this if I used a dict instead, but I would lose the simple returnval.foo access.
AttrDict implementations perhaps? But those come in 3rd party packages, not in standard lib.
Mocks. Not what I want to be using here, because this is not testing code and I want an exception thrown if returnval.foo does not exist.
Module/class attribute assignment. Yes, I could assign attribute to an existing object in the namespace, like a class or a module declaration. But then that would essentially be assigning attributes to a singleton and successive function calls would clobber each other.