Merge pull request #121 from guibog/master

Some more about style and web dev
This commit is contained in:
Kenneth Reitz
2012-04-23 08:17:40 -07:00
2 changed files with 168 additions and 0 deletions
+41
View File
@@ -2,6 +2,9 @@
Web Applications
================
As a powerful scripting language adapted to both fast prototyping
and bigger projects, Python is widely used in Web applications
development.
Context
:::::::
@@ -203,6 +206,44 @@ Gondor publishes guides to deploying `Django projects
<https://gondor.io/support/setting-up-pinax/>`_ on their platform.
Templating
::::::::::
Most WSGI applications are responding to HTTP requests to serve
content in HTML or other markup languages. Instead of generating directly
textual content from Python, the concept of separation of concerns
advise us to use templates. A template engine manage a suite of
template files, with a system of hierarchy and inclusion to
avoid unnecessary repetition, and is in charge of rendering
(generating) the actual content, filling the static content
of the templates with the dynamic content generated by the
application.
As template files are
sometime written by designers or front-end developpers,
it can be difficult to handle increasing complexity.
Some general good pratices apply to the part of the
application passing dynamic content to the template engine,
and to the templates themselves.
- Template files should be passed only the dynamic
content that is needed for rendering the template. Avoid
to be tempted to pass additional content "just in case":
it is easier to add some missing variable when needed than to remove
a likely unused variable later.
- Many template engine allow for complex statements
or assignments in the template itself, and many
allow some Python code to be evaluated in the
templates. This convenience can lead to uncontrolled
increase in complexity, and often harder to find bugs.
- It is often possible or necessary to mix javascript templates with
HTML templates. A sane approach to this design is to isolate
the parts where the HTML template passes some variable content
to the javascript code.
.. rubric:: References
.. [1] `The mod_python project is now officially dead <http://blog.dscpl.com.au/2010/06/modpython-project-is-now-officially.html>`_
+127
View File
@@ -1,6 +1,133 @@
Code Style
==========
If you ask to Python programmers what they like the most in Python, they will
often say it is its high readability. Indeed, a high level of readability of
the code is at the heart of the design of the Python language, following the
recognised fact that code is read much more often than it is written.
One reason for Python code to be easily read and understood is its relatively
complete set of Code Style guidelines and "Pythonic" idioms.
On the opposite, when a veteran Python developper (a Pythonistas) point to some
parts of a code and say it is not "Pythonic", it usually means that these lines
of code do not follow the common guidelines and fail to express the intent is
what is considered the best (hear: most readable) way.
On some border cases, no best way has been agreed upon on how to express
an intent in Python code, but these cases are rare.
General concepts
----------------
Explicit code
~~~~~~~~~~~~~
While any kind of black magic is possible with Python, the
most explicit and straightforward manner is preferred.
**Bad**
.. code-block:: python
def make_complex(\*args):
x, y = args
return dict(\**locals())
**Good**
.. code-block:: python
def make_complex(x, y):
return {'x': x, 'y': y}
In the good code above, x and y are explicitely received from
the caller, and an explicit dictionary is returned. The developer
using this function knows exactly what to do by reading the
first and last lines, which is not the case with the bad example.
One statement per line
~~~~~~~~~~~~~~~~~~~~~~
While some compound statements such as list comprehensions are
allowed and appreciated for their brevity and their expressivity,
it is bad practice to have two disjoint statements on the same line.
**Bad**
.. code-block:: python
print 'one'; print 'two'
if x == 1: print 'one'
if <complex comparison> and <other complex comparison>:
# do something
**Good**
.. code-block:: python
print 'one'
print 'two'
if x == 1:
print 'one'
cond1 = <complex comparison>
cond2 = <other complex comparison>
if cond1 and cond2:
# do something
Avoid the magical wand
~~~~~~~~~~~~~~~~~~~~~~
A powerful tool for hackers, Python comes with a very rich set of hooks and
tools allowing to do almost any kind of tricky tricks. For instance, it is
possible to change how objects are created and instanciated, it is possible to
change how the Python interpreter imports modules, it is even possible (and
recommended if needed) to embed C routines in Python.
However, all these options have many drawbacks and it is always better to use
the most straightforward way to achieve your goal. The main drawback is that
readability suffers deeply from them. Many code analysis tools, such as pylint
or pyflakes, will be unable to parse this "magic" code.
We consider that a Python developer should know about these nearly infinite
possibilities, because it grows the confidence that no hard-wall will be on the
way. However, knowing how to use them and particularly when **not** to use
them is the most important.
Like a Kungfu master, a pythonistas knows how to kill with a single finger, and
never do it.
We are all consenting adults
~~~~~~~~~~~~~~~~~~~~~~~~~~~~
As seen above, Python allows many tricks, and some of them are potentially
dangerous. A good example is that any client code can override an object's
properties and methods: There is no "private" keyword in Python. This
philosophy, very different from highly defensive languages like Java, which
give a lot of mechanism to prevent any misuse, is expressed by the saying: "We
are consenting adults".
This doesn't mean that, for example, no properties are considered private, and
that no proper encapsulation is possible in Python. But, instead of relying on
concrete walls erected by the developers between their code and other's, the
Python community prefers to rely on a set of convention indicating that these
elements should not be accessed directly.
The main convention for private properties and implementation details is to
prefix all "internals" with an underscore. If the client code breaks this rule
and access to these marked elements, any misbehavior or problems encountered if
the code is modified is the responsibility of the client code.
Using this convention generously is encouraged: any method or property that is
not intended to be used by client code should be prefixed with an underscore.
This will guarantee a better separation of duties and easier modifications of
existing code, and it will always be possible to publicize a private property,
while privatising a public property might be a much harder operation.
Idioms
------