I am confused about the use of typing and docstring. Aren't they duplicate information? For example:
def my_func(name: str):
"""
print a name.
Parameters
----------
name : str
a given name
"""
print(name)
Isn't the information "name: str" given two times?
CodePudding user response:
Putting the type as a type hint and as part of the docstring would be redundant. It is also prone to human errors since one could easily forget updating one of them, thus effort is constantly needed to keep them both in sync.
The documentation for type hints also mentioned about it:
Docstrings. There is an existing convention for docstrings, based on the Sphinx notation (
:type arg1: description
). This is pretty verbose (an extra line per parameter), and not very elegant. We could also make up something new, but the annotation syntax is hard to beat (because it was designed for this very purpose).
But all of this depends on your usecase.
- If you are using static-type checkers such as mypy (e.g. it would fail if you passed an int
123
to a variable with type hintstr
) or IDE such as PyCharm (e.g. it would highlight inconsistencies between type hint and passed arguments), then you should keep on using type hint. This is the preferable way as it points out possible errors in the code you've written. - If you are using tools such as Sphinx, or Swagger, or something else, note that this tools display your classes and methods along with their docstrings for the purposes of documentation. So if you want to maintain such documentation for clarity to other readers and want to have the types included, then you might want to put the type hint in the docstring as well. But if you think such detail isn't needed as most of the time only the description in the docstring is relevant, then no need to add the type hint in the docstring.
In the long run, the more sustainable way is to have those tools (Sphinx, Swagger, etc.) use the type hint as part of the documentation instead of relying solely on the text in the docstring. For sphinx, I found this library sphinx-autodoc-typehints that performs it already.
allowing you to migrate from this:
def format_unit(value, unit): """ Formats the given value as a human readable string using the given units. :param float|int value: a numeric value :param str unit: the unit for the value (kg, m, etc.) :rtype: str """ return '{} {}'.format(value, unit)
to this:
from typing import Union def format_unit(value: Union[float, int], unit: str) -> str: """ Formats the given value as a human readable string using the given units. :param value: a numeric value :param unit: the unit for the value (kg, m, etc.) """ return '{} {}'.format(value, unit)
So it seems like there are already enhancements on this topic that will make the definition of types more consistent and not redundant.