35dd43254282f34eda46cda595548afcb36d094b
[python-guide.git] / docs / writing / structure.rst
1 Structuring Your Project
2 ========================
3
4 By "structure" we mean the decisions you make concerning
5 how your project best meets its objective. We need to consider how to 
6 best leverage Python's features to create clean, effective code.
7 In practical terms, "structure" means making clean code whose logic and
8 dependencies are clear as well as how the files and folders are organized
9 in the filesystem. 
10
11 Which functions should go into which modules? How does data flow through
12 the project? What features and functions can be grouped together and 
13 isolated? By answering questions like these you can begin to plan, in
14 a broad sense, what your finished product will look like.
15
16 In this section we take a closer look at Python's module and import 
17 systems as they are the central element to enforcing structure in your 
18 project. We then discuss various perspectives on how to build code which
19 can be extended and tested reliably.
20
21
22 Structure is Key
23 ----------------
24
25 Thanks to the way imports and modules are handled in Python, it is
26 relatively easy to structure a Python project. Easy, here, means
27 that you do not have many constraints and that the module
28 importing model is easy to grasp. Therefore, you are left with the
29 pure architectural task of crafting the different parts of your
30 project and their interactions.
31
32 Easy structuring of a project means it is also easy
33 to do it poorly. Some signs of a poorly structured project
34 include:
35
36 - Multiple and messy circular dependencies: if your classes
37   Table and Chair in furn.py need to import Carpenter from workers.py
38   to answer a question such as table.isdoneby(),
39   and if conversely the class Carpenter needs to import Table and Chair,
40   to answer the question carpenter.whatdo(), then you
41   have a circular dependency. In this case you will have to resort to
42   fragile hacks such has using import statements inside
43   methods or functions.
44
45 - Hidden coupling: each and every change in Table's implementation
46   breaks 20 tests in unrelated test cases because it breaks Carpenter's code,
47   which requires very careful surgery to adapt the change. This means
48   you have too many assumptions about Table in Carpenter's code or the
49   reverse.
50
51 - Heavy usage of global state or context: instead of explicitly
52   passing ``(height, width, type, wood)`` to each other, Table
53   and Carpenter rely on global variables that can be modified
54   and are modified on the fly by different agents. You need to
55   scrutinize all access to these global variables to understand why
56   a rectangular table became a square, and discover that remote
57   template code is also modifying this context, messing with
58   table dimensions.
59
60 - Spaghetti code: multiple pages of nested if clauses and for loops
61   with a lot of copy-pasted procedural code and no
62   proper segmentation are known as spaghetti code. Python's
63   meaningful indentation (one of its most controversial features) make
64   it very hard to maintain this kind of code. So the good news is that
65   you might not see too much of it.
66
67 - Ravioli code is more likely in Python: it consists of hundreds of
68   similar little pieces of logic, often classes or objects, without
69   proper structure. If you never can remember if you have to use
70   FurnitureTable, AssetTable or Table, or even TableNew for your
71   task at hand, you might be swimming in ravioli code.
72
73
74 Modules
75 -------
76
77 Python modules are one of the main abstraction layers available and probably the
78 most natural one. Abstraction layers allow separating code into parts holding
79 related data and functionality.
80
81 For example, a layer of a project can handle interfacing with user actions,
82 while another would handle low-level manipulation of data. The most natural way
83 to separate these two layers is to regroup all interfacing functionality
84 in one file, and all low-level operations in another file. In this case,
85 the interface file needs to import the low-level file. This is done with the
86 `import` and `from ... import` statements.
87
88 As soon as you use `import` statements you use modules. These can be either built-in
89 modules such as `os` and `sys`, third-party modules you have installed in your
90 environment, or your project's internal modules.
91
92 To keep in line with the style guide, keep module names short, lowercase, and
93 be sure to avoid using special symbols like the dot (.) or question mark (?).
94 So a file name like `my.spam.py` is one you should try to avoid! Naming this way 
95 will interfere with the way python looks for modules.
96
97 In this example python expects to find a "spam.py" file in a folder named "my"
98 which is not the case. There is an 
99 `example <http://docs.python.org/tutorial/modules.html#packages>`_ of how the 
100 dot notation should be used in the python docs.
101
102 If you'd like you could name it as `my_spam.py` but even our friend the 
103 underscore should not be seen often in module names.
104
105 Aside for some naming restrictions, nothing special is required for a Python file
106 to be a module, but the import mechanism needs to be understood in order to use
107 this concept properly and avoid some issues.
108
109 Concretely, the `import modu` statement will look for the proper file, which is
110 `modu.py` in the same directory as the caller if it exists.  If it is not
111 found, the Python interpreter will search for `modu.py` in the "path"
112 recursively and raise an ImportError exception if it is not found.
113
114 Once `modu.py` is found, the Python interpreter will execute the module in an
115 isolated scope. Any top-level statement in `modu.py` will be executed,
116 including other imports if any. Function and class definitions are stored in
117 the module's dictionary.
118
119 Then, the module's variables, functions, and classes will be available to the caller
120 through the module's namespace, a central concept in programming that is
121 particularly helpful and powerful in Python.
122
123 In many languages, an `include file` directive is used by the preprocessor to
124 take all code found in the file and 'copy' it into the caller's code. It is
125 different in Python: the included code is isolated in a module namespace, which
126 means that you generally don't have to worry that the included code could have
127 unwanted effects, e.g. override an existing function with the same name.
128
129 It is possible to simulate the more standard behavior by using a special syntax
130 of the import statement: `from modu import *`. This is generally considered bad
131 practice. **Using `import *` makes code harder to read and makes dependencies less
132 compartmentalized**.
133
134 Using `from modu import func` is a way to pinpoint the function you want to
135 import and put it in the global namespace. While much less harmful than `import
136 *` because it shows explicitly what is imported in the global namespace, its
137 advantage over a simpler `import modu` is only that it will save some typing.
138
139 **Very bad**
140
141 .. code-block:: python
142
143     [...]
144     from modu import *
145     [...]
146     x = sqrt(4)  # Is sqrt part of modu? A builtin? Defined above?
147
148 **Better**
149
150 .. code-block:: python
151
152     from modu import sqrt
153     [...]
154     x = sqrt(4)  # sqrt may be part of modu, if not redefined in between
155
156 **Best**
157
158 .. code-block:: python
159
160     import modu
161     [...]
162     x = modu.sqrt(4)  # sqrt is visibly part of modu's namespace
163
164 As said in the section about style, readability is one of the main features of
165 Python. Readability means to avoid useless boilerplate text and clutter,
166 therefore some efforts are spent trying to achieve a certain level of brevity.
167 But terseness and obscurity are the limits where brevity should stop. Being
168 able to tell immediately where a class or function comes from, as in the
169 `modu.func` idiom, greatly improves code readability and understandability in
170 all but the simplest single file projects.
171
172
173 Packages
174 --------
175
176 Python provides a very straightforward packaging system, which is simply an
177 extension of the module mechanism to a directory.
178
179 Any directory with an __init__.py file is considered a Python package. The
180 different modules in the package are imported in a similar manner as plain
181 modules, but with a special behavior for the __init__.py file, which is used to
182 gather all package-wide definitions.
183
184 A file modu.py in the directory pack/ is imported with the statement `import
185 pack.modu`. This statement will look for an __init__.py file in `pack`, execute
186 all of its top-level statements. Then it will look for a file `pack/modu.py` and
187 execute all of its top-level statements. After these operations, any variable,
188 function, or class defined in modu.py is available in the pack.modu namespace.
189
190 A commonly seen issue is to add too much code to __init__.py
191 files. When the project complexity grows, there may be sub-packages and
192 sub-sub-packages in a deep directory structure, and then, importing a single item
193 from a sub-sub-package will require executing all __init__.py files met while
194 traversing the tree.
195
196 Leaving an __init__.py file empty is considered normal and even a good practice,
197 if the package's modules and sub-packages do not need to share any code.
198
199 Lastly, a convenient syntax is available for importing deeply nested packages:
200 `import very.deep.module as mod`. This allows you to use `mod` in place of the verbose
201 repetition of `very.deep.module`.
202
203 Object-oriented programming
204 ---------------------------
205
206 Python is sometimes described as an object-oriented programming language. This
207 can be somewhat misleading and needs to be clarified.
208
209 In Python, everything is an object, and can be handled as such. This is what is
210 meant when we say that, for example, functions are first-class objects.
211 Functions, classes, strings, and even types are objects in Python: like any
212 objects, they have a type, they can be passed as function arguments, they may
213 have methods and properties. In this understanding, Python is an
214 object-oriented language.
215
216 However, unlike Java, Python does not impose object-oriented programming as the
217 main programming paradigm. It is perfectly viable for a Python project to not
218 be object-oriented, i.e. to use no or very few class definitions, class
219 inheritance, or any other mechanisms that are specific to object-oriented
220 programming.
221
222 Moreover, as seen in the modules_ section, the way Python handles modules and
223 namespaces gives the developer a natural way to ensure the
224 encapsulation and separation of abstraction layers, both being the most common
225 reasons to use object-orientation. Therefore, Python programmers have more
226 latitude to not use object-orientation, when it is not required by the business
227 model.
228
229 There are some reasons to avoid unnecessary object-orientation. Defining
230 custom classes is useful when we want to glue together some state and some
231 functionality. The problem, as pointed out by the discussions about functional
232 programming, comes from the "state" part of the equation.
233
234 In some architectures, typically web applications, multiple instances of Python
235 processes are spawned to respond to external requests that can
236 happen at the same time. In this case, holding some state into instantiated
237 objects, which means keeping some static information about the world, is prone
238 to concurrency problems or race-conditions. Sometimes, between the initialization of
239 the state of an object (usually done with the __init__() method) and the actual use
240 of the object state through one of its methods, the world may have changed, and
241 the retained state may be outdated. For example, a request may load an item in
242 memory and mark it as read by a user. If another request requires the deletion
243 of this item at the same, it may happen that the deletion actually occurs after
244 the first process loaded the item, and then we have to mark as read a deleted
245 object.
246
247 This and other issues led to the idea that using stateless functions is a
248 better programming paradigm.
249
250 Another way to say the same thing is to suggest using functions and procedures
251 with as few implicit contexts and side-effects as possible. A function's
252 implicit context is made up of any of the global variables or items in the persistence layer
253 that are accessed from within the function. Side-effects are the changes that a function makes
254 to it's implicit context. If a function saves or deletes data in a global variable or
255 in the persistence layer, it is said to have a side-effect.
256
257 Carefully isolating functions with context and side-effects from functions with
258 logic (called pure functions) allow the following benefits:
259
260 - Pure functions are deterministic: given a fixed input,
261   the output will always be the same.
262
263 - Pure functions are much easier to change or replace if they need to
264   be refactored or optimized.
265
266 - Pure functions are easier to test with unit-tests: There is less
267   need for complex context setup and data cleaning afterwards.
268
269 - Pure functions are easier to manipulate, decorate_, and pass-around.
270
271 In summary, pure functions, without any context or side-effects, are more
272 efficient building blocks than classes and objects for some architectures.
273
274 Obviously, object-orientation is useful and even necessary in many cases, for
275 example when developing graphical desktop applications or games, where the
276 things that are manipulated (windows, buttons, avatars, vehicles) have a
277 relatively long life of their own in the computer's memory.
278
279
280 Decorators
281 ----------
282
283 The Python language provides a simple yet powerful syntax called 'decorators'.
284 A decorator is a function or a class that wraps (or decorate) a function
285 or a method. The 'decorated' function or method will replace the original
286 'undecorated' function or method. Because functions are first-class objects
287 in Python, it can be done 'manually', but using the @decorator syntax is
288 clearer and thus preferred.
289
290 .. code-block:: python
291
292     def foo():
293         # do something
294
295     def decorator(func):
296         # manipulate func
297         return func
298
299     foo = decorator(foo)  # Manually decorate
300
301     @decorator
302     def bar():
303         # Do something
304     # bar() is decorated
305
306 This mechanism is useful for separating concerns and avoiding
307 external un-related logic 'polluting' the core logic of the function
308 or method. A good example of a piece of functionality that is better handled
309 with decoration is memoization or caching: you want to store the results of an
310 expensive function in a table and use them directly instead of recomputing
311 them when they have already been computed. This is clearly not part
312 of the function logic.
313
314 Dynamic typing
315 --------------
316
317 Python is said to be dynamically typed, which means that variables
318 do not have a fixed type. In fact, in Python, variables are very
319 different from what they are in many other languages, specifically
320 strongly-typed languages. Variables are not a segment of the computer's
321 memory where some value is written, they are 'tags' or 'names' pointing
322 to objects. It is therefore possible for the variable 'a' to be set to
323 the value 1, then to the value 'a string', then to a function.
324
325 The dynamic typing of Python is often considered to be a weakness, and indeed
326 it can lead to complexities and hard-to-debug code. Something
327 named 'a' can be set to many different things, and the developer or the
328 maintainer needs to track this name in the code to make sure it has not
329 been set to a completely unrelated object.
330
331 Some guidelines help to avoid this issue:
332
333 - Avoid using variables for different things.
334
335 **Bad**
336
337 .. code-block:: python
338
339     a = 1
340     a = 'a string'
341     def a():
342         pass  # Do something
343
344 **Good**
345
346 .. code-block:: python
347
348     count = 1
349     msg = 'a string'
350     def func():
351         pass  # Do something
352
353 Using short functions or methods helps reduce the risk
354 of using the same name for two unrelated things.
355
356 It is better to use different names even for things that are related,
357 when they have a different type:
358
359 **Bad**
360
361 .. code-block:: python
362
363     items = 'a b c d'  # This is a string...
364     items = items.split(' ')  # ...becoming a list
365     items = set(items)  # ...and then a set
366
367 There is no efficiency gain when reusing names: the assignments
368 will have to create new objects anyway. However, when the complexity
369 grows and each assignment is separated by other lines of code, including
370 'if' branches and loops, it becomes harder to ascertain what a given
371 variable's type is.
372
373 Some coding practices, like functional programming, recommend never reassigning a variable.
374 In Java this is done with the `final` keyword. Python does not have a `final` keyword
375 and it would be against its philosophy anyway. However, it may be a good
376 discipline to avoid assigning to a variable more than once, and it helps
377 in grasping the concept of mutable and immutable types.
378
379 Mutable and immutable types
380 ---------------------------
381
382 Python has two kinds of built-in or user-defined types.
383
384 Mutable types are those that allow in-place modification
385 of the content. Typical mutables are lists and dictionaries:
386 All lists have mutating methods, like append() or pop(), and
387 can be modified in place. The same goes for dictionaries.
388
389 Immutable types provide no method for changing their content.
390 For instance, the variable x set to the integer 6 has no "increment" method. If you
391 want to compute x + 1, you have to create another integer and give it
392 a name.
393
394 .. code-block:: python
395
396     my_list = [1, 2, 3]
397     my_list[0] = 4
398     print my_list  # [4, 2, 3] <- The same list as changed
399
400     x = 6
401     x = x + 1  # The new x is another object
402
403 One consequence of this difference in behavior is that mutable
404 types are not "stable", and therefore cannot be used as dictionary
405 keys.
406
407 Using properly mutable types for things that are mutable in nature
408 and immutable types for things that are fixed in nature
409 helps to clarify the intent of the code.
410
411 For example, the immutable equivalent of a list is the tuple, created
412 with ``(1, 2)``. This tuple is a pair that cannot be changed in-place,
413 and can be used as a key for a dictionary.
414
415 One peculiarity of Python that can surprise beginners is that
416 strings are immutable. This means that when constructing a string from
417 its parts, it is much more efficient to accumulate the parts in a list,
418 which is mutable, and then glue ('join') the parts together when the
419 full string is needed. One thing to notice, however, is that list
420 comprehensions are better and faster than constructing a list in a loop
421 with calls to append().
422
423 **Bad**
424
425 .. code-block:: python
426
427     # create a concatenated string from 0 to 19 (e.g. "012..1819")
428     nums = ""
429     for n in range(20):
430       nums += str(n)   # slow and inefficient
431     print nums
432
433 **Good**
434
435 .. code-block:: python
436     
437     # create a concatenated string from 0 to 19 (e.g. "012..1819")
438     nums = []
439     for n in range(20):
440       nums.append(str(n))
441     print "".join(nums)  # much more efficient
442
443 **Best**
444
445 .. code-block:: python
446
447     # create a concatenated string from 0 to 19 (e.g. "012..1819")
448     print "".join([str(n) for n in range(20)])
449
450 One final thing to mention about strings is that using join() is not always
451 best. In the instances where you are creating a new string from a pre-determined
452 number of strings, using the addition operator is actually faster, but in cases
453 like above or in cases where you are adding to an existing string, using join()
454 should be your preferred method.
455
456 .. code-block:: python
457
458     foo = 'foo'
459     bar = 'bar'
460
461     foobar = foo + bar  # This is good
462     foo += 'ooo'  # This is bad, instead you should do:
463     foo = ''.join([foo, 'ooo'])
464
465 Vendorizing Dependencies
466 ------------------------
467
468
469
470 Runners
471 -------
472
473
474 Further Reading
475 ---------------