Dynamic generation of doc-strings of dynamically generated classes

George Sakkis gsakkis at rutgers.edu
Mon Oct 17 10:01:58 EDT 2005


"Mikael Olofsson" <mikael at isy.liu.se> wrote:

> Hi!
>
> I've asked Google, but have not found any useful information there.
>
> Situation: I have a base class, say
>
>  >>> class base(object):
>          ImportantClassAttribute = None
>
> Now, I want to dynamically generate subclasses of base. That's not a
> problem. However, I very much want those subclasses to have individual
> doc-strings. More precicely, I want that important class attribute to be
> reflected in the doc-string. That's the problem. The only way I've
> managed to accomplish that is something like the following.
>
>  >>> ImportantClassAttribute = 7
>  >>> docString = 'The case %s.' % (ImportantClassAttribute,)
>  >>> exec('''class new(base):
>           """%s"""
>           pass ''' % (docString,))
>  >>> new.ImportantClassAttribute = ImportantClassAttribute
>  >>> new.__doc__
> 'The case 7.'
>
> This works as intended. The subclasses do get the doc-strings I want
> them to have, and I can live with this solution. But: This solution does
> not strike me as especially beautiful or readable. My first naïve
> attempt was instead the following.
>
>  >>> class new(base):
> pass
>
>  >>> new.ImportantClassAttribute = 7
>  >>> new.__doc__ = ('The case %(ImportantClassAttribute)s.'
>        % new.__dict__)
>
> Traceback (most recent call last):
>    File "<pyshell#35>", line 1, in -toplevel-
>      new.__doc__ = ('The case %(ImportantClassAttribute)s.'
> TypeError: attribute '__doc__' of 'type' objects is not writable
>
> This is readable to me, but apparently not the way to go, since I'm not
> allowed to replace the doc-string like this. I've also tried a number of
> other ways, but they all stumble on similar reasons.
>
> Any ideas? Am I stuck with the clumsy exec-solution, or are there other
> ways to dynamically generate doc-strings of classes?

There's nothing specifically about doc-strings, but you can create and customise a whole class
dynamically:

def makeBaseSubclass(impClassAttr):
    return type('new_%s' % impClassAttr,
                     (base,object),
                    {'ImportantClassAttribute': impClassAttr,
                      '__doc__': 'The case %s' % impClassAttr})

>>> new = makeBaseSubclass(7)
>>> new.ImportantClassAttribute
7
>>> new.__doc__
'The case 7'


HTH,
George





More information about the Python-list mailing list