1

I am making a large number (close to 100) of classes programmatically and I would like to be able to set the docstring of the class. Each of the class docstrings will have the same basic structure, with specific pieces to be filled in. I would like to define a template string and then populate it with class specific arguments when the class is created.

As a contrived example of what I am after, consider the following

class_docstr = """
This is the docstring for the {name} class.
"""


class A(object):

    def __init__(self):
        pass


class B(object):

    def __init__(self):
        pass


class C(object):

    def __init__(self):
        pass

What I would like to do is somehow set A.__doc__ = class_docstr.format(name="A") so that when I call help(A) I see something like this:

class A(__builtin__.object)
 |  This is the docstring for the A class.  

I believe I might need to use a metaclass to do this, but I am not sure how.

spencerlyon2
  • 9,476
  • 4
  • 30
  • 39
  • You can update the `__doc__` key of the class dictionary inside of `__new__` method of a metaclass, note that this has to be done before the class is actually created. – Ashwini Chaudhary Jan 08 '15 at 21:50
  • This would sort of defeat the purpose of docstrings since glancing at the class definition wouldn't give you an obvious way of seeing the documentation. Is there a reason your docstrings need to be generated in this way? – astex Jan 08 '15 at 21:53
  • 1
    I want the docstrings more for interactive exploration at the python or ipython repl and for automatically generating html documentation via sphinx, not to document the source. – spencerlyon2 Jan 08 '15 at 21:55
  • @AshwiniChaudhary -- Why do you say that it needs to happen before the class is created? The __doc__ attribute should be writable... – mgilson Jan 08 '15 at 21:56
  • @mgilson It is not possible with classes that are of type . But hmm... a metaclass makes it possible. http://ideone.com/UPKHq8 – Ashwini Chaudhary Jan 08 '15 at 22:07

2 Answers2

3

You can set the docstring by assigning to the __doc__ class variable inside the class definition:

class A(object):
    __doc__ = class_docstr.format(name="A")

    # whatever else

This works, even though assigning to A.__doc__ does not work later, after the class has been created.

Blckknght
  • 100,903
  • 11
  • 120
  • 169
0

If you really want to use a metaclass here, it shouldn't be hard...

>>> class Meta(type):
...   def __init__(cls, *args):
...     super(Meta, cls).__init__(*args)
...     cls.__doc__ = class_docstr.format(name=cls.__name__)
... 
>>> class A(object):
...   __metaclass__ = Meta
... 
>>> A.__doc__
'\nThis is the docstring for the A class.\n'

With that said, this is almost certainly overkill...

mgilson
  • 300,191
  • 65
  • 633
  • 696
  • I don't really want to use a meta class, but don't know of a cleaner solution. Can you offer an alternative? Perhaps Blckknght's suggestion? – spencerlyon2 Jan 08 '15 at 21:56
  • Sure, that will work. Then you have to specify the name of the class twice, but that's not the end of the world. Alternatively, you can create a class decorator to do the job... Basically -- You have a number of options and it really just depends on how verbose you want to be... – mgilson Jan 08 '15 at 22:00
  • This doesn't work in Python 2, where you can't modify the `__doc__` variable after the class has been created. You can add a `__doc__` value to the class dictionary in a metaclass `__new__` method, but that's a bit more verbose than what you have here. – Blckknght Jan 08 '15 at 22:06
  • @Blckknght It is possible if the class's type is something other than `type`. So, a simple decorator based approach is not possible. – Ashwini Chaudhary Jan 08 '15 at 22:08
  • http://bugs.python.org/issue12773, resolved only for Python 3.3+. :/ Same issue in PyPy 2.4.0 BTW. – Ashwini Chaudhary Jan 08 '15 at 22:30