When I'm creating a docstring, sometimes I want to refer to a value, for instance:
def try_download(data, path):
"""Tries to download ATTEMPTS times, catching socket errors."""
Where ATTEMPTS
is just a constant int defined at the start of the file. But would it be better to write it so that it's generating a string actually indicating what the value is, ie.
def try_download(data, path):
"""Tries to download {} times, catching socket errors.""".format(ATTEMPTS)
The advantage to this, would be that someone else reading dynamically from the function would get a more helpful message indicating the actual number. However someone reading the actual script has a slightly less readable sentence. There's also a degree of danger that this makes the docstring error prone in that errors could occur, but in reality if it's replaced by a number that can't be printed, the actual function will have bigger problems than it's docstring.
So is this worrying over nothing, or is it better to stay safe and not insert variables into docstrings?
Best Answer
The approach you're describing doesn't actually produce a docstring. It doesn't result in the __doc__ property of the function being set, which means that it's not available to the help function, and wouldn't be available to (typical) automated documentation generators. Here's a simple example that shows this in action. First, a function with a "traditional" docstring:
Note that the __doc__ property is set, and help will show the contents of that string. Now, let's try with the dynamically generated "docstring". I put docstring in scare quotes because it's not actually a docstring.
There's no value for foo.__doc__, and help doesn't display anything aside from the function declaration, which means that the system didn't interpret the value as a docstring. That's not really surprising, since the first expression in the function body isn't a string, it's a function call to a member function of a string.
So, to answer the questions,
There are ways to dynamically update a docstring, viz., by setting the __doc__ property of the function, but that's not what your approach is doing. Whether it's good or bad practice probably depends on the application. If you're dynamically generating some functions and want to programatically assign documentation to them, it might be fine. In the way that you're describing though, it simply doesn't work.
It depends on what you mean by "reading dynamically from the function". It might be helpful to someone reading the source, but it's definitely not helpful to someone who is looking at the output of help, or who is reading the value of the __doc__ property.