22

I need to dynamically create a class. To go in futher detail I need to dynamically create a subclass of Django's Form class.

By "dynamically" I intend to create a class based on configuration provided by a user.


e.g.

I want a class named CommentForm which should subclass the Form class.

The class should have a list of chosen attributes.

....in this case

name = forms.CharField()
comment = forms.CharField(widget=forms.Textarea())

Any useful tips? :)

martineau
  • 112,593
  • 23
  • 157
  • 280
RadiantHex
  • 23,687
  • 47
  • 145
  • 240
  • 1
    "I need to dynamically create a class." This is so rarely needed that you have to provide a **lot** more information in order for this question to make sense. – S.Lott Oct 12 '10 at 14:55

2 Answers2

35

You can create classes on the fly by calling the type built-in, passing appropriate arguments along, like:

CommentForm = type("CommentForm", (Form,), { 
    'name': forms.CharField(),
    ...
})

It works with new-style classes. I am not sure, whether this would also work with old-style classes.

Dirk
  • 29,982
  • 6
  • 78
  • 100
  • 1
    This will work with old-style classes as long as they aren't the only base class(es). So e.g. you can do `type(name, (OldStyleClass, object), attrib_dict)` but not `type(name, (OldStyleClass,), attrib_dict)`. If you need the resulting class to be old-style, you can still parametrize the class creation by putting it in a function, like in [this answer](http://stackoverflow.com/questions/3915024/dynamically-creating-classes-python/3915110#3915110). – intuited Oct 15 '10 at 11:46
14

Classes can be defined almost anywhere.

def newclass(val):
  class C(object):
    def __str__(self):
      return str(val)
  return C

MyClass = newclass(5)
m = MyClass()
print str(m)
Ignacio Vazquez-Abrams
  • 740,318
  • 145
  • 1,296
  • 1,325
  • 1
    It's maybe not immediately obvious for some readers that this technique can be used to set the base class for `C`. This is useful if you need to dynamically create an old-style class for some reason. – intuited Oct 15 '10 at 11:50