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
  • 119,623
  • 25
  • 170
  • 301
RadiantHex
  • 24,907
  • 47
  • 148
  • 244
  • 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

36

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
  • 30,623
  • 8
  • 82
  • 102
  • 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
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 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