Reputation: 2589
How do I create objects on the fly in Python? I often want to pass information to my Django templates which is formatted like this:
{'test': [a1, a2, b2], 'test2': 'something else', 'test3': 1}
which makes the template look untidy. so I think it's better to just create an object which is like:
class testclass():
self.test = [a1,a2,b2]
self.test2 = 'someting else'
self.test3 = 1
testobj = testclass()
so I can do:
{{ testobj.test }}
{{ testobj.test2 }}
{{ testobj.test3 }}
instead of calling the dictionary.
Since I just need that object once, is it possible to create it without writing a class first? Is there any short-hand code? Is it ok to do it like that or is it bad Python?
Upvotes: 30
Views: 24987
Reputation: 3193
if you just need a "QuickRecord" you can simply declare a empty class
and you can use it without having to instantiate an object...
(just seize the dynamic features of python language... "á la Javascript")
# create an empty class...
class c1:pass
# then just add/change fields at your will
c1.a = "a-field"
c1.b = 1
c1.b += 10
print( c1.a, " -> ", c1.b )
# this has even the 'benesse' of easealy taking a
# snapshot whenever you want
c2 = c1()
print( c2.a, " -> ", c2.b )
Upvotes: 3
Reputation: 17254
Here's a rogue, minimalist way to create an object. A class is an object, so just commandeer the class definition syntax as if it were a Python object literal:
class testobj(object):
test = [a1,a2,b2]
test2 = 'something else'
test3 = 1
Class variables are the members of the object, and are easily referenced:
assert testobj.test3 == 1
This is weird, a class never used as a class: it's never instantiated. But it's a low-clutter way to make an ad hoc, singleton object: The class itself is your object.
Upvotes: 2
Reputation: 2046
for the sake of completeness, there is also recordclass
:
from recordclass import recordclass
Test = recordclass('Test', ['test', 'test1', 'test2'])
foo = Test(test=['a1','a2','b2'], test1='someting else', test2=1)
print(foo.test)
.. ['a1', 'a2', 'b2']
Upvotes: 1
Reputation: 76
use building function type: document
>>> class X:
... a = 1
...
>>> X = type('X', (object,), dict(a=1))
first and second X are identical
Upvotes: 3
Reputation: 2022
There is another solution in Python 3.3+ types.SimpleNamespace
from types import SimpleNamespace
test_obj = SimpleNamespace(a=1, b=lambda: {'hello': 42})
test_obj.a
test_obj.b()
Upvotes: 31
Reputation: 16453
You can use built-in type function:
testobj = type('testclass', (object,),
{'test':[a1,a2,b2], 'test2':'something else', 'test3':1})()
But in this specific case (data object for Django templates), you should use @Xion's solution.
Upvotes: 34
Reputation: 3883
The code below also require a class to be created however it is shorter:
>>>d = {'test':['a1','a2','b2'], 'test2':'something else', 'test3':1}
>>> class Test(object):
... def __init__(self):
... self.__dict__.update(d)
>>> a = Test()
>>> a.test
['a1', 'a2', 'b2']
>>> a.test2
'something else'
Upvotes: 0
Reputation: 22780
In Django templates, the dot notation (testobj.test
) can resolve to the Python's []
operator. This means that all you need is an ordinary dict:
testobj = {'test':[a1,a2,b2], 'test2':'something else', 'test3':1}
Pass it as testobj
variable to your template and you can freely use {{ testobj.test }}
and similar expressions inside your template. They will be translated to testobj['test']
. No dedicated class is needed here.
Upvotes: 28