|
1 | 1 | Documenting Your Code
|
2 | 2 | =====================
|
3 | 3 |
|
4 |
| -Documenting your code is extremely important. It is debatably even |
5 |
| -more important than testing. |
| 4 | +With readability of the code being a main focus for Python developers, proper |
| 5 | +commenting is naturally important. Some best practice apply to code comments |
| 6 | +and project documents, depending on the scope of the project. |
| 7 | + |
| 8 | +Project documents |
| 9 | +----------------- |
| 10 | + |
| 11 | +A README file at the root directory give general information to the users and |
| 12 | +the maintainers. It should be raw text or written in some very easy to read |
| 13 | +markup, such as reStructuredText and Markdown. It should contain a few lines |
| 14 | +explaining the purpose of the project or the library (without assuming the user |
| 15 | +knows anything about the project), the url of the main source for the software, |
| 16 | +and some basic credit information. This file is the main entry point for |
| 17 | +readers of the code. |
| 18 | + |
| 19 | +An INSTALL file is less often necessary with python, except if the dependencies |
| 20 | +are complex or unusual, or if some C modules need to be compiled before use. |
| 21 | +The installation instructions are often reduced to one command, such as ``pip |
| 22 | +install module`` or ``python setup.py install`` and added to the README file. |
| 23 | + |
| 24 | +A LICENSE file should always be present and specify the license under which the |
| 25 | +software is made available to the public. |
| 26 | + |
| 27 | +A TODO file or a TODO section in README should list the planned modifications |
| 28 | +of the code. |
| 29 | + |
| 30 | +A CHANGELOG file or section in README should compile a short overview of the |
| 31 | +changes in the code base for the latest versions. |
| 32 | + |
| 33 | +Documentation |
| 34 | +------------- |
| 35 | + |
| 36 | +As the project or library reaches a certain level of complexity, it may require |
| 37 | +a fuller documentation, which can be of different flavors: |
| 38 | + |
| 39 | +The introduction may show a very short overview of what can be done with the |
| 40 | +product, using one or two extremely simplified use cases. |
| 41 | + |
| 42 | +The tutorials will show in more details some main use cases. The reader will |
| 43 | +follow a step-by-step procedure to set-up a working prototype. |
| 44 | + |
| 45 | +The API reference, which is often generated automatically from the code, will |
| 46 | +list all publicly available interfaces, their parameters and their return |
| 47 | +values, with an explanation of their use. |
| 48 | + |
| 49 | +Some documents intended for developers might give guidance about code |
| 50 | +convention and general design decision of the project. |
| 51 | + |
| 52 | +Comments |
| 53 | +-------- |
| 54 | + |
| 55 | +Comments are written directly inside the code, either using the hash sign (#) |
| 56 | +or a docstring_. |
| 57 | + |
| 58 | +Finding the correct balance between undocumented code and verbose and useless |
| 59 | +comment boilerplates is difficult, and is the subject of heated discussion |
| 60 | +among developers. |
| 61 | + |
| 62 | +The following guidelines seem to be most commonly agreed upon: |
| 63 | + |
| 64 | +**Wrong or outdated comments are worse than no comments at all.** Following the |
| 65 | +saying that it is better, on a boat, to know that we do not know were we are |
| 66 | +than to wrongly believe we know where we are, wrong or outdated comments can be |
| 67 | +misleading for the maintainers, slow down considerably bug hunting or |
| 68 | +refactoring, and then, when discovered wrong, they will throw suspicion on all |
| 69 | +other comments in the code, regardless of their individual correctness. |
| 70 | + |
| 71 | +**No need comments for perfect code...** An hypothetical perfectly readable |
| 72 | +code, with a crystal clear logic stream, expressive variable and function |
| 73 | +names, orthogonal segmentation passing exactly between the flesh and the bones, |
| 74 | +and no implicit assumptions of any kind, would not require any comment at all. |
| 75 | +When striving for coding excellence, it is useful to see any existing comment, |
| 76 | +or any feeling of a need for a comment, as the sign that the code do not |
| 77 | +express clearly enough its intent and can be improved. |
| 78 | + |
| 79 | +**.. but no code is perfect.** Perfect code is a chimere, it exists only in |
| 80 | +our dreams. In real life, a code base is full of trade offs, and comments are |
| 81 | +often needed in the most difficult parts. Moreover, any special case, any |
| 82 | +obscure hack, any monkey patch and any ugly workaround MUST be signaled and |
| 83 | +explained by a proper comment. This should be enforced by the law! |
| 84 | + |
| 85 | +**TODOs** are special comments that a developer write as a reminder for later |
| 86 | +use. It is said that its original intent was that someone might, one day, |
| 87 | +search for the string "TODO" in the code base and actually roll their sleeves |
| 88 | +and start *to do the TODOs*. There is no avalaible record that it ever |
| 89 | +happened. However, TODOs comment are still very useful, because they mark the |
| 90 | +current limits of the code, and it is not unlikely that, when required to add a |
| 91 | +new behavior to the actual code, looking at the TODOs will show where to start. |
| 92 | + |
| 93 | +**Do not use triple-quote strings to comment code.** A common operation when |
| 94 | +modifiying code is to comment out some lines or even a full function or class |
| 95 | +definition. This can be done by adding triple-quotes around the code block to |
| 96 | +be skipped, but this is not a good pratice, because line-oriented command-line |
| 97 | +tools such as ``grep`` will not be aware that the commented code is inactive. |
| 98 | +It is better to add hashes at the proper indentation level for every commented |
| 99 | +line. Good editors allow to do this with few keystrokes (ctrl-v on Vim). |
| 100 | + |
| 101 | +**Bad** |
| 102 | + |
| 103 | +.. code-block:: python |
| 104 | +
|
| 105 | + def tricky_function(): |
| 106 | + ''' |
| 107 | + if foo: |
| 108 | + do_bar() |
| 109 | + ''' |
| 110 | + return baz |
| 111 | +
|
| 112 | + def tricky_function(): |
| 113 | + #if foo: |
| 114 | + #do_bar() |
| 115 | + return baz |
| 116 | +
|
| 117 | +**Good** |
| 118 | + |
| 119 | +.. code-block:: python |
| 120 | +
|
| 121 | + def tricky_function(): |
| 122 | + #if foo: |
| 123 | + # do_bar() |
| 124 | + return baz |
| 125 | +
|
6 | 126 |
|
7 | 127 |
|
8 | 128 | The Basics
|
|
0 commit comments