diff --git a/docs/writing/documentation.rst b/docs/writing/documentation.rst index b27f8dac6..c4cb0fd19 100644 --- a/docs/writing/documentation.rst +++ b/docs/writing/documentation.rst @@ -104,26 +104,38 @@ line. Good editors allow to do this with few keystrokes (ctrl-v on Vim). def tricky_function(): ''' + Commented out because its breaks something. if foo: do_bar() ''' return baz def tricky_function(): + # Commented out because its breaks something. #if foo: #do_bar() return baz + + def tricky_function(): + # Commented out because its breaks something. + # if foo: + # do_bar() + return baz + **Good** .. code-block:: python def tricky_function(): + # Commented out because its breaks something. #if foo: # do_bar() return baz - +Note that comment text is properly written and separated from the hash by a +space. Commented code is not separated from the hash by an additional space; +this helps when uncommented the code. The Basics :::::::::: diff --git a/docs/writing/structure.rst b/docs/writing/structure.rst index c1478bc72..a0afbaf28 100644 --- a/docs/writing/structure.rst +++ b/docs/writing/structure.rst @@ -172,6 +172,83 @@ Lastly, a convenient syntax is available for importing deeply nested packages: `import very.deep.module as mod` allow to use `mod` in place of the verbose repetition of `very.deep.module` in front of each calls to module items. +Object-oriented programming +--------------------------- + +Python is sometime described as an object-oriented programming language. This +can be somewhat misleading and need to be clarified. + +In Python, everything is an object, and can be handled as such. This is what is +meant when we say that, for example, functions are first-class objects. +Functions, classes, strings, and even types are objects in Python: like any +objects, they have a type, they can be passed as function arguments, they may +have methods and properties. In this understanding, Python is an +object-oriented language. + +However, unlike Java, Python do not impose object-oriented programming as the +main programming paradigm. It is perfectly viable for a Python project to not +be object-oriented, ie. to use no or very few class definitions, class +inheritance, and any other mechanism that are specific to object-oriented +programming. + +Moreover, as seen in the modules_ section, the way Python handles modules and +namespaces gives directly to the developer a natural way to ensure +encapsulation and separation of abstraction layers, both being the most common +reasons to use object-orientation. Therefore, Python programmers have more +latitude to not use object-orientation, when it is not required by the business +model to be constructed. + +There are some reasons to avoid unnecessary object-orientation. Definining +custom classes is useful when we want to glue together some state and some +functionality. The problem, as pointed out by the discussions about functional +programming, comes from the "state" part of the equation. + +In some architectures, typically web applications, instances of Python +processes are spawned simultaneously to answer to external requests that can +happen at the same time. In this case, holding some state into instanciated +objects, which means keeping some static information about the world, is prone +to concurrency problems or race-conditions: between the initialization of the +state of an object, usually done with the __init__() method, and the actual use +of the object state through one of its method, the world may have changed, and +the retained state may be outdated. For example, a request may load an item in +memory and mark it as read by a user. If another request requires the deletion +of this item at the same, it may happen that the deletion actually occur after +the first process loaded the item, and then we have to mark as read a deleted +object. + +This and other issues led to the idea that using stateless functions is a +better programming paradigm. + +Another way to say the same thing is to propose to use functions and procedures +with as few implicit context and side-effects as possible. A function's +implicit context is decelable when the function body refers to some global +variables or fetches data from the persistence layer. Side-effects are the +opposite: if a function body modifies the global context or save or delete data +on the persistence layer, it is said to have side-effect. + +Isolating carefully functions with context and side-effects from functions with +logic (called pure functions) allow the following benefits: + +- Pure functions are more likely to be deterministic: given a fixed input, + the output will always be the same. + +- Pure functions are much easier to change or replace if they need to + be refactored or optimized. + +- Pure functions are easier to test with unit-tests: There is less + need for complex context setup and data cleaning afterwards. + +- Pure functions are easier to manipulate, decorate_, pass-around. + +In summary, pure functions, without any context or side-effects, are more +efficient building blocks than classes and objects for some architectures. + +Obviously, object-orientation is useful and even necessary in many cases, for +example when developing graphical desktop applications or games, where the +things that are manipulated (windows, buttons, avatars, vehicles) have a +relatively long life of their own in the computer's memory. + + Vendorizing Dependencies ------------------------