Diferències

Ací es mostren les diferències entre la revisió seleccionada i la versió actual de la pàgina.

Enllaç a la visualització de la comparació

Ambdós costats versió prèvia Revisió prèvia
Següent revisió
Revisió prèvia
info:cursos:pue:python-pcpp1:m2:4.1 [14/12/2023 11:29] mateinfo:cursos:pue:python-pcpp1:m2:4.1 [19/12/2023 11:02] (actual) – [One-line docstrings] mate
Línia 112: Línia 112:
   * **multi-line docstrings** – they are used for more difficult cases, and should consist of a summary line followed by one blank line and a more elaborate description.   * **multi-line docstrings** – they are used for more difficult cases, and should consist of a summary line followed by one blank line and a more elaborate description.
 Let's talk a bit more about each of them. Let's talk a bit more about each of them.
 +
 +=== One-line docstrings
 +**One-line docstrings** should be used for rather simple, obvious, and short descriptions. They should take up one line only, and be surrounded by triple double quotes (the closing quotes should be on the same line as the opening quotes as this helps to keep the code clean and elegant).
 +
 +Important notes:
 +
 +  * a docstring should begin with an upper-case letter (unless an identifier begins the sentence) and end with a period;
 +  * a docstring should prescribe the code segment's effect, not describe it. In other words, it should take the form of an imperative (e.g. "Do this", "Return that", "Compute this", "Convert that", etc.), not a description (e.g. "Does this", "Returns that", "Forms this", "Extends that", etc.). For example:
 +<code python>
 +def greeting(name):
 +    """Take a name and return its replicated form."""
 +    return name * 2
 +</code>
 +  * a docstring should not just simply repeat the function or method parameters. For example:
 +<code python ❌>def my_function(x, y):
 +    """my_function(x, y) -> list"""
 +...</code>
 +<code python ✔>
 +def my_function(x, y):
 +    """Compute the angles and return a list of coordinates."""
 +...</code>
 +  * Do not use a blank line above or under a one-line docstring unless you're documenting a class, in which case you should put a blank line after all the docstrings that document it:
 +<code python ❌>def calculate_tax(x, y):
 +
 +    """I am a one-line docstring."""
 +    
 +    return (x+y) * 0.25
 +</code>
 +=== Multi-line docstrings
 +Multi-line docstrings should be used for non-obvious cases and more detailed descriptions of code segments. They should have a summary line, similar to what a one-line docstring looks like, followed by a blank line and a more elaborate description. The summary line may be located on the same line as the open triple double quotes, or put on the next line. The end quotes should be put on a separate line.
 +
 +Important notes:
 +
 +  * a multi-line docstring should be indented to the same level as the open quotes, for example:
 +<code python>
 +def king_creator(name="Greg", ordinal="I", country="Neverland"):
 +    """Create a king following the article title naming convention.
 +    
 +    Keyword arguments:
 +    :arg name: the king's name (default: Greg)
 +    :type name: str
 +    :arg ordinal: Roman ordinal number (default: I)
 +    :type ordinal: str
 +    :arg country: the country ruled (default: Neverland)
 +    :type country: str
 +    """
 +    if name == "Voldemort":
 +        return "Voldemort is a reserved name."
 +    ...
 +</code>
 +  * you should insert a blank line after all the multi-line docstrings that are documenting a class;
 +  * script docstrings (in the sense of stand-alone programs/single file executables) should document the script's function, command line syntax, environment variables, and files. The description should be balanced in a way that it helps new users understand the script's usage, as well as provide a quick reference to all the program's features for the more experienced user;
 +  * module docstrings should list the classes, exceptions, and functions exported by the module;
 +  * package docstrings (understood as the docstring of the package's %%__init__%%.py module) should list the modules and subpackages exported by the package;
 +  * docstrings for functions and class methods should summarize their behavior and provide information about the arguments (including optional arguments), values, exceptions, restrictions, etc.
 +  * class docstrings should also summarize its behavior as well as document the public methods and instance variables. For example:
 +<code python>class Vehicle:
 +    """A class to represent a Vehicle.
 +    
 +    Attributes:
 +    -----------
 +    vehicle_type: str
 +        The type of the vehicle, e.g. a car.
 +    id_number: int
 +        The vehicle identification number.
 +    is_autonomous: bool
 +        self-driving -> True, not self-driving -> False
 +
 +    
 +    Methods:
 +    --------
 +    report_location(lon=45.00, lat=90.00)
 +        Print the vehicle id number and its current location.
 +        (default longitude=45.00, default latitude=90.00)
 +    """
 +    
 +    def __init__(self, vehicle_type, id_number, is_autonomous=True):
 +        """
 +        Parameters:
 +        -----------
 +        vehicle_type: str
 +            The type of the vehicle, e.g. a car.
 +        id_number: int
 +            The vehicle identification number.
 +        is_autonomous: bool, optional
 +            self-driving -> True (default), not self-driving -> False
 +        """
 +        
 +        self.vehicle_type = vehicle_type
 +        self.id_number = id_number
 +        self.is_autonomous = is_autonomous
 +    
 +    def report_location(self, id_number, lon=45.00, lat=90.00):
 +        """
 +        Print the vehicle id number and its current location.
 +        
 +        Parameters:
 +        -----------
 +        id_number: int
 +            The vehicle identification number.
 +        lon: float, optional
 +            The vehicle's current longitude (default is 45.00)
 +        lat: float, optional
 +            The vehicle's current latitude (default is 90.00)
 +        """
 +
 +    ...
 +    ...
 +    ...
 +</code>
 +=== Docstring formatting types
 +You may have noticed that we have used two different docstring formats for documenting the ''king_creator()'' function and the ''Vehicle'' class. The first type of formatting is called **reStructuredText**, and it's the official Python documentation standard explained and described in [[https://peps.python.org/pep-0287/|PEP 287]]. The second example uses the **NumPy/SciPy docstrings** format (for details, click [[https://numpydoc.readthedocs.io/en/latest/format.html|here]], which is a combination of the [[https://google.github.io/styleguide/pyguide.html#38-comments-and-docstrings|Google docstrings]] format and the reStructuredText format.
 +
 +Both formatting types are good for the purposes of creating formal documentation, and both of them are supported by [[https://www.sphinx-doc.org/en/master/usage/extensions/example_google.html|Sphinx]], one of the most popular Python documentation generators.
 +
 +Sphinx is a great tool for creating documentation for software development projects. It uses reStructuredText as its markup language, and has a lot of useful features, such as supporting the HTML output format, automatic testing of code snippets, extensive cross-references, and a hierarchical structure, which lets you define a document tree. Check it out.
 +
 +== How to document a project
 +When documenting a Python project, depending on the nature of the project (i.e. private, shared, public, open source/public domain), you should first and foremost define its users and think about their needs. Creating a **user persona** may come in handy here as it will help you identify the ways the users will use your project.
 +
 +This means you can easily improve their experience by thinking about how they're going to utilize your code and trying to predict the most common issues they may come across when doing so.
 +
 +Generally, a project should contain the following documentation elements:
 +
 +  * a **readme**, which provides a brief summary of the project, its purpose, and possibly some installation guidelines;
 +  * an **examples.py** file, which is a script that demonstrates a few examples of how to utilize the project;
 +  * a **license** in the form of a txt file (particularly important for Open Source and Public Domain projects)
 +  * a **how to contribute** file which provides information about the possible ways of contributing to the project (shared, open source, and public domain projects).
 +Because documenting your code can be a rather exhausting and time-consuming activity, you are definitely encouraged to use some of the tools that could help you auto-generate documentation in the desired format, and deal with documentation updates and versioning in an effective and efficient way.
 +
 +There are many documentation tools and resources available, such as Sphinx, which we've already mentioned, or the highly popular pdoc, and many more. We encourage you to follow this path.
 +
 +== Linters and fixers
 +How do you maintain the good quality of your code? Well, you already know that you can follow the style guides such as PEP 8 or PEP 257, and write your code in a readable and consistent way. You can (and possibly should) adopt the Zen of Python philosophy, with all its good advice for writing an elegant and maintainable code, and use the type hinting mechanism. You can observe how others write code and document it as part of their projects (Look at the Python Standard Library or the Requests library), and learn from them. Finally, you can use //linters//.
 +
 +Right. But what is a **linter**? Well, it's a tool that helps you write your code, because it **analyzes it for any stylistic anomalies and programming errors against a set of pre-defined rules**. In other words, it's a program that analyzes your code and reports such issues as structural and syntax errors, consistency breakups, and a lack of compatibility with best practices or code style guidelines such as PEP 8. The most popular linters are: Flake8, Pylint, Pyflakes, Pychecker, Mypy, and Pycodestyle (formerly Pep8) – the official linter tool to check Python code against PEP 8 conventions.
 +
 +A **fixer**, on the other hand, is a program that helps you fix these issues and format your code to be consistent with the adopted standards. The most popular fixers are: Black, YAPF, and autopep8.
 +
 +Most editors and IDEs (e.g. PyCharm, Spyder, Atom, Sublime Text, Visual Studio, Eclipse + PyDev, VIM, or Thonny) support linters, which means you can run them in the background as you write code. This makes it possible to detect, highlight, and identify many problem areas in your code, such as typos, wrong tabbing and indentation issues, function calls with the wrong number of arguments, stylistic inconsistencies, dangerous code patterns, and many more, and automatically format your code to a pre-defined specification.
 +
 +That being said, we encourage you to explore the territory of linters and fixers yourself, and start using them to maintain high-quality Python code, and simply make your life easier.
 +
 +== How to access docstrings
 +We've nearly made it to the end of our journey with PEP 257 and docstrings. The last question that still remains to be fully answered is: how can we actually access docstrings?
 +
 +We do it by using the Python __doc__ attribute – if any string literals are present after the definition of a function/module/class/method, then they are associated with the object as its __doc__ attribute, and this attribute provides the documentation of that object.
 +
 +Run the code in the editor to see what happens. Your output should be like this:<code>The summary line goes here.
 +
 + A more elaborate description of the function.
 +
 + Parameters:
 + a: int (description)
 + b: int (description)
 +
 + Returns:
 + int: Description of the return value.</code>
 +But there's also another way to access the documentation strings – you can use the ''help()'' function. Make a small amendment in your code: replace the ''print'' function invocation with the following line:<code python>help(my_fun)
 +</code>
 +Run the code and see what happens. What are your conclusions?
 +
 +As you can see, the output is lengthier and more descriptive:<code>Help on function my_fun in module __main__:
 +
 +my_fun(a, b)
 +    The summary line goes here.
 +    
 +    A more elaborate description of the function.
 +    
 +    Parameters:
 +    a: int (description)
 +    b: int (description)
 +    
 +    Returns:
 +    int: Description of the return value.</code>
 +Now try to access the docstrings of any of the Python built-in functions (e.g. print()). Then import a module and access the module documentation. Experiment with the %%__doc__%% method and the ''help()'' function. See what outputs you get and how they differ from each other. Use them to learn more information about the Python built-in objects.
 +
 +You've learned a lot. You can be proud of yourself!
 +
 +<code python>def my_fun(a, b):
 +    """The summary line goes here.
 +
 +    A more elaborate description of the function.
 +
 +    Parameters:
 +    a: int (description)
 +    b: int (description)
 +
 +    Returns:
 +    int: Description of the return value.
 +    """
 +    return a*b
 +
 +print(my_fun.__doc__)
 +</code>
  • info/cursos/pue/python-pcpp1/m2/4.1.1702549745.txt.gz
  • Darrera modificació: 06/07/2026 18:29
  • (edició externa)