|
1 | 1 | Code Style |
2 | 2 | ========== |
3 | 3 |
|
| 4 | +If you ask to Python programmers what they like the most in Python, they will |
| 5 | +often say it is its high readability. Indeed, a high level of readability of |
| 6 | +the code is at the heart of the design of the Python language, following the |
| 7 | +recognised fact that code is read much more often than it is written. |
| 8 | + |
| 9 | +One reason for Python code to be easily read and understood is its relatively |
| 10 | +complete set of Code Style guidelines and "Pythonic" idioms. |
| 11 | + |
| 12 | +On the opposite, when a veteran Python developper (a Pythonistas) point to some |
| 13 | +parts of a code and say it is not "Pythonic", it usually means that these lines |
| 14 | +of code do not follow the common guidelines and fail to express the intent is |
| 15 | +what is considered the best (hear: most readable) way. |
| 16 | + |
| 17 | +On some border cases, no best way has been agreed upon on how to express |
| 18 | +an intent in Python code, but these cases are rare. |
| 19 | + |
| 20 | +General concepts |
| 21 | +---------------- |
| 22 | + |
| 23 | +Explicit code |
| 24 | +~~~~~~~~~~~~~ |
| 25 | + |
| 26 | +While any kind of black magic is possible with Python, the |
| 27 | +most explicit and straightforward manner is preferred. |
| 28 | + |
| 29 | +**Bad** |
| 30 | + |
| 31 | +.. code-block:: python |
| 32 | +
|
| 33 | + def make_complex(\*args): |
| 34 | + x, y = args |
| 35 | + return dict(\**locals()) |
| 36 | +
|
| 37 | +**Good** |
| 38 | +
|
| 39 | +.. code-block:: python |
| 40 | +
|
| 41 | + def make_complex(x, y): |
| 42 | + return {'x': x, 'y': y} |
| 43 | +
|
| 44 | +In the good code above, x and y are explicitely received from |
| 45 | +the caller, and an explicit dictionary is returned. The developer |
| 46 | +using this function knows exactly what to do by reading the |
| 47 | +first and last lines, which is not the case with the bad example. |
| 48 | +
|
| 49 | +One statement per line |
| 50 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 51 | +
|
| 52 | +While some compound statements such as list comprehensions are |
| 53 | +allowed and appreciated for their brevity and their expressivity, |
| 54 | +it is bad practice to have two disjoint statements on the same line. |
| 55 | +
|
| 56 | +**Bad** |
| 57 | +
|
| 58 | +.. code-block:: python |
| 59 | +
|
| 60 | + print 'one'; print 'two' |
| 61 | +
|
| 62 | + if x == 1: print 'one' |
| 63 | +
|
| 64 | + if <complex comparison> and <other complex comparison>: |
| 65 | + # do something |
| 66 | +
|
| 67 | +**Good** |
| 68 | +
|
| 69 | +.. code-block:: python |
| 70 | +
|
| 71 | + print 'one' |
| 72 | + print 'two' |
| 73 | +
|
| 74 | + if x == 1: |
| 75 | + print 'one' |
| 76 | +
|
| 77 | + cond1 = <complex comparison> |
| 78 | + cond2 = <other complex comparison> |
| 79 | + if cond1 and cond2: |
| 80 | + # do something |
| 81 | +
|
| 82 | +
|
| 83 | +Avoid the magical wand |
| 84 | +~~~~~~~~~~~~~~~~~~~~~~ |
| 85 | +
|
| 86 | +A powerful tool for hackers, Python comes with a very rich set of hooks and |
| 87 | +tools allowing to do almost any kind of tricky tricks. For instance, it is |
| 88 | +possible to change how objects are created and instanciated, it is possible to |
| 89 | +change how the Python interpreter imports modules, it is even possible (and |
| 90 | +recommended if needed) to embed C routines in Python. |
| 91 | +
|
| 92 | +However, all these options have many drawbacks and it is always better to use |
| 93 | +the most straightforward way to achieve your goal. The main drawback is that |
| 94 | +readability suffers deeply from them. Many code analysis tools, such as pylint |
| 95 | +or pyflakes, will be unable to parse this "magic" code. |
| 96 | +
|
| 97 | +We consider that a Python developer should know about these nearly infinite |
| 98 | +possibilities, because it grows the confidence that no hard-wall will be on the |
| 99 | +way. However, knowing how to use them and particularly when **not** to use |
| 100 | +them is the most important. |
| 101 | +
|
| 102 | +Like a Kungfu master, a pythonistas knows how to kill with a single finger, and |
| 103 | +never do it. |
| 104 | +
|
| 105 | +We are all consenting adults |
| 106 | +~~~~~~~~~~~~~~~~~~~~~~~~~~~~ |
| 107 | +
|
| 108 | +As seen above, Python allows many tricks, and some of them are potentially |
| 109 | +dangerous. A good example is that any client code can override an object's |
| 110 | +properties and methods: There is no "private" keyword in Python. This |
| 111 | +philosophy, very different from highly defensive languages like Java, which |
| 112 | +give a lot of mechanism to prevent any misuse, is expressed by the saying: "We |
| 113 | +are consenting adults". |
| 114 | +
|
| 115 | +This doesn't mean that, for example, no properties are considered private, and |
| 116 | +that no proper encapsulation is possible in Python. But, instead of relying on |
| 117 | +concrete walls erected by the developers between their code and other's, the |
| 118 | +Python community prefers to rely on a set of convention indicating that these |
| 119 | +elements should not be accessed directly. |
| 120 | +
|
| 121 | +The main convention for private properties and implementation details is to |
| 122 | +prefix all "internals" with an underscore. If the client code breaks this rule |
| 123 | +and access to these marked elements, any misbehavior or problems encountered if |
| 124 | +the code is modified is the responsibility of the client code. |
| 125 | +
|
| 126 | +Using this convention generously is encouraged: any method or property that is |
| 127 | +not intended to be used by client code should be prefixed with an underscore. |
| 128 | +This will guarantee a better separation of duties and easier modifications of |
| 129 | +existing code, and it will always be possible to publicize a private property, |
| 130 | +while privatising a public property might be a much harder operation. |
4 | 131 |
|
5 | 132 | Idioms |
6 | 133 | ------ |
|
0 commit comments