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.
Python Code can be dynamically imported and classes can be dynamically created at run-time. Classes can be dynamically created using the type() function in Python. The type() function is used to return the type of the object. The above syntax returns the type of object.
You can create custom dynamic objects by using the classes in the System. Dynamic namespace. For example, you can create an ExpandoObject and specify the members of that object at run time. You can also create your own type that inherits the DynamicObject class.
We already know that an object is a container of some data and methods that operate on that data. In Python, an object is created from a class. To create an object, you have to define a class first.
Just define your own class to do it:
class Expando(object): pass ex = Expando() ex.foo = 17 ex.bar = "Hello"
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).
obj = type('Expando', (object,), {})() obj.foo = 71 obj.bar = 'World'
Or just, which does the same as above using dict
argument:
obj = type('Expando', (object,), {'foo': 71, 'bar': 'World'})()
For Python 3, passing object to bases
argument is not necessary (see type
documentation).
But for simple cases instantiation doesn't have any benefit, so is okay to do:
ns = type('Expando', (object,), {'foo': 71, 'bar': 'World'})
At the same time, personally I prefer a plain class (i.e. without instantiation) for ad-hoc test configuration cases as simplest and readable:
class ns: foo = 71 bar = 'World'
In Python 3.3+ there is exactly what OP asks for, types.SimpleNamespace
. It's just:
A simple
object
subclass that provides attribute access to its namespace, as well as a meaningful repr.Unlike
object
, withSimpleNamespace
you can add and remove attributes. If aSimpleNamespace
object is initialized with keyword arguments, those are directly added to the underlying namespace.
import types obj = types.SimpleNamespace() obj.a = 123 print(obj.a) # 123 print(repr(obj)) # namespace(a=123)
However, in stdlib of both Python 2 and Python 3 there's argparse.Namespace
, which has the same purpose:
Simple object for storing attributes.
Implements equality by attribute names and values, and provides a simple string representation.
import argparse obj = argparse.Namespace() obj.a = 123 print(obj.a) # 123 print(repr(obj)) # Namespace(a=123)
Note that both can be initialised with keyword arguments:
types.SimpleNamespace(a = 'foo',b = 123) argparse.Namespace(a = 'foo',b = 123)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With