Re: docstring that use globals?



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?

A simple way is

spam.__doc__ = spam.__doc__ % globals()

which can easily be turned into a decorator:

def update_doc(f):
f.__doc__ = f.__doc__ % f.func_globals
return f

@update_doc
def spam(...):
...

Peter
.