@@ -9,7 +9,7 @@ Structure is Key
9
9
----------------
10
10
11
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
12
+ relatively easy to structure a Python project. Easy, here, means
13
13
that you do not have many constraints and that the module
14
14
importing model is easy to grasp. Therefore, you are left with the
15
15
pure architectural task of crafting the different parts of your
@@ -19,7 +19,7 @@ Easy structuring of a project means it is also easy
19
19
to do it poorly. Some signs of a poorly structured project
20
20
include:
21
21
22
- - Multiple and messy circular dependencies: If your classes
22
+ - Multiple and messy circular dependencies: if your classes
23
23
Table and Chair in furn.py need to import Carpenter from workers.py
24
24
to answer a question such as table.isdoneby(),
25
25
and if conversely the class Carpenter needs to import Table and Chair,
@@ -28,13 +28,13 @@ include:
28
28
fragile hacks such has using import statements inside
29
29
methods or functions.
30
30
31
- - Hidden coupling: Each and every change in Table's implementation
31
+ - Hidden coupling: each and every change in Table's implementation
32
32
breaks 20 tests in unrelated test cases because it breaks Carpenter's code,
33
33
which requires very careful surgery to adapt the change. This means
34
34
you have too many assumptions about Table in Carpenter's code or the
35
35
reverse.
36
36
37
- - Heavy usage of global state or context: Instead of explicitly
37
+ - Heavy usage of global state or context: instead of explicitly
38
38
passing ``(height, width, type, wood) `` to each other, Table
39
39
and Carpenter rely on global variables that can be modified
40
40
and are modified on the fly by different agents. You need to
@@ -43,14 +43,14 @@ include:
43
43
template code is also modifying this context, messing with
44
44
table dimensions.
45
45
46
- - Spaghetti code: Multiple pages of nested if clauses and for loops
46
+ - Spaghetti code: multiple pages of nested if clauses and for loops
47
47
with a lot of copy-pasted procedural code and no
48
- proper segmentation are known as spaghetti code. Python's
48
+ proper segmentation are known as spaghetti code. Python's
49
49
meaningful indentation (one of its most controversial features) make
50
50
it very hard to maintain this kind of code. So the good news is that
51
51
you might not see too much of it.
52
52
53
- - Ravioli code is more likely in Python: It consists of hundreds of
53
+ - Ravioli code is more likely in Python: it consists of hundreds of
54
54
similar little pieces of logic, often classes or objects, without
55
55
proper structure. If you never can remember if you have to use
56
56
FurnitureTable, AssetTable or Table, or even TableNew for your
@@ -186,14 +186,14 @@ objects, they have a type, they can be passed as function arguments, they may
186
186
have methods and properties. In this understanding, Python is an
187
187
object-oriented language.
188
188
189
- However, unlike Java, Python do not impose object-oriented programming as the
189
+ However, unlike Java, Python does not impose object-oriented programming as the
190
190
main programming paradigm. It is perfectly viable for a Python project to not
191
191
be object-oriented, i.e. to use no or very few class definitions, class
192
192
inheritance, or any other mechanisms that are specific to object-oriented
193
193
programming.
194
194
195
195
Moreover, as seen in the modules _ section, the way Python handles modules and
196
- namespaces gives the developer a natural way to ensure
196
+ namespaces gives the developer a natural way to ensure the
197
197
encapsulation and separation of abstraction layers, both being the most common
198
198
reasons to use object-orientation. Therefore, Python programmers have more
199
199
latitude to not use object-orientation, when it is not required by the business
@@ -208,8 +208,8 @@ In some architectures, typically web applications, multiple instances of Python
208
208
processes are spawned to respond to external requests that can
209
209
happen at the same time. In this case, holding some state into instantiated
210
210
objects, which means keeping some static information about the world, is prone
211
- to concurrency problems or race-conditions. Sometime between the initialization of the
212
- state of an object, usually done with the __init__() method, and the actual use
211
+ to concurrency problems or race-conditions. Sometimes, between the initialization of
212
+ the state of an object ( usually done with the __init__() method) and the actual use
213
213
of the object state through one of its methods, the world may have changed, and
214
214
the retained state may be outdated. For example, a request may load an item in
215
215
memory and mark it as read by a user. If another request requires the deletion
@@ -230,7 +230,7 @@ in the persistence layer, it is said to have a side-effect.
230
230
Carefully isolating functions with context and side-effects from functions with
231
231
logic (called pure functions) allow the following benefits:
232
232
233
- - Pure functions are more likely to be deterministic: given a fixed input,
233
+ - Pure functions are deterministic: given a fixed input,
234
234
the output will always be the same.
235
235
236
236
- Pure functions are much easier to change or replace if they need to
@@ -257,7 +257,7 @@ The Python language provides a simple yet powerful syntax called 'decorators'.
257
257
A decorator is a function or a class that wraps (or decorate) a function
258
258
or a method. The 'decorated' function or method will replace the original
259
259
'undecorated' function or method. Because functions are first-class objects
260
- in Python it can be done 'manually' but using the @decorator syntax is
260
+ in Python, it can be done 'manually', but using the @decorator syntax is
261
261
clearer and thus preferred.
262
262
263
263
.. code-block :: python
0 commit comments