In python how can we create a new object without having a predefined Class and later dynamically add properties to it ?
example:
dynamic_object = Dynamic()
dynamic_object.dynamic_property_a = "abc"
dynamic_object.dynamic_property_b = "abcdefg"
What is the best way to do it?
EDIT Because many people advised in comments that I might not need this.
The thing is that I have a function that serializes an object's properties. For that reason, I don't want to create an object of the expected class due to some constructor restrictions, but instead create a similar one, let's say like a mock, add any "custom" properties I need, then feed it back to the function.
If you take metaclassing approach from @Martijn's answer, @Ned's answer can be rewritten shorter (though it's obviously less readable, but does the same thing).
Or just, which does the same as above using
dict
argument:For Python 3, passing object to
bases
argument is not necessary (seetype
documentation).But for simple cases instantiation doesn't have any benefit, so is okay to do:
At the same time, personally I prefer a plain class (i.e. without instantiation) for ad-hoc test configuration cases as simplest and readable:
Update
In Python 3.3+ there is exactly what OP asks for,
types.SimpleNamespace
. It's just:However, in stdlib of both Python 2 and Python 3 there's
argparse.Namespace
, which has the same purpose:Note that both can be initialised with keyword arguments:
Just define your own class to do it:
Use the
collections.namedtuple()
class factory to create a custom class for your return value:The returned value can be used both as a tuple and by attribute access:
One way that I found is also by creating a lambda. It can have sideeffects and comes with some properties that are not wanted. Just posting for the interest.
Using an object just to hold values isn't the most Pythonic style of programming. It's common in programming languages that don't have good associative containers, but in Python, you can use use a dictionary:
You can also use a "dictionary literal" to define the dictionary's contents all at once:
Or, if your keys are all legal identifiers (and they will be, if you were planning on them being attribute names), you can use the
dict
constructor with keyword arguments as key-value pairs:Filling out a dictionary is in fact what Python is doing behind the scenes when you do use an object, such as in Ned Batchelder's answer. The attributes of his
ex
object get stored in a dictionary,ex.__dict__
, which should end up being equal to an equivalentdict
created directly.Unless attribute syntax (e.g.
ex.foo
) is absolutely necessary, you may as well skip the object entirely and use a dictionary directly.