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