docstring that use globals?

MRAB python at mrabarnett.plus.com
Sat Oct 16 12:14:29 EDT 2010


On 16/10/2010 16:51, kj wrote:
>
>
> Consider the following Python snippet:
>
> SEPARATOR = '+'
>
> def spam(ham, eggs):
>      """Return a hash of ham and eggs.
>
>      The variables ham and eggs are tuples of strings.  The returned
>      "hash" is a dict made from the pairs returned by zip(ham, eggs).
>      If ham contains repeated keys, the corresponding values in eggs
>      are concatenated using the string "SEPARATOR".
>
>      For example, spam(('a', 'b', 'a'), ('x', 'y', 'z')) returns
>      {'a': 'xSEPARATORz', 'b': 'y'}."""
>
>      # implementation follows...
>
>
> Of course, as written, the docstring above is no good.  All
> occurrences of the string "SEPARATOR" in it should be replaced with
> the actual value of the global variable SEPARATOR, which in this
> case is the string '+'.
>
> My first attempt at achieving this effect was the following:
>
> SEPARATOR = '+'
>
> def spam(ham, eggs):
>      """Return a hash of ham and eggs.
>
>      The variables ham and eggs are tuples of strings.  The returned
>      "hash" is a dict made from the pairs returned by zip(ham, eggs).
>      If ham contains repeated keys, the corresponding values in eggs
>      are concatenated using the string "%(SEPARATOR)s".
>
>      For example, spam(('a', 'b', 'a'), ('x', 'y', 'z')) returns
>      {'a': 'x%(SEPARATOR)sz', 'b': 'y'}.""" % globals()
>
>      # implementation follows...
>
>
> ...which, of course (in retrospect), does not work, since only a
> string literal, and not any ol' string-valued expression, at the
> beginning of a function's body can serve as a docstring.
>
> What's the best way to achieve what I'm trying to do?
>
> (Of course, all these acrobatics are hardly worth the effort for
> the simple example I give above.  In the actual situation I'm
> dealing with, however, there are a lot more docstrings and global
> variables in the mix, and at this early stage of the development,
> the values of the globals are still fluid.  I'm trying to minimize
> the effort required to keep the docstrings current, while still
> retaining the freedom to adjust the values of the globals.  Also,
> FWIW, most of these globals are merely default values that can be
> overridden at runtime.)
>
Use a decorator:

SEPARATOR = '+'

def expand_doc(func):
     func.__doc__ = func.__doc__ % globals()
     return func

@expand_doc
def spam(ham, eggs):
     """Return a hash of ham and eggs.

     The variables ham and eggs are tuples of strings.  The returned
     "hash" is a dict made from the pairs returned by zip(ham, eggs).
     If ham contains repeated keys, the corresponding values in eggs
     are concatenated using the string "%(SEPARATOR)s".

     For example, spam(('a', 'b', 'a'), ('x', 'y', 'z')) returns
     {'a': 'x%(SEPARATOR)sz', 'b': 'y'}."""

     # implementation follows...



More information about the Python-list mailing list