mirror of
https://github.com/kennethreitz/python-guide.git
synced 2026-06-05 14:50:19 +00:00
Merge pull request #522 from vpzee/master
Corrected lines to be no longer than 78 characters.
This commit is contained in:
+49
-38
@@ -29,31 +29,33 @@ following lines::
|
||||
|
||||
With these settings, newlines are inserted after 79 characters and indentation
|
||||
is set to 4 spaces per tab. If you also use Vim for other languages, there is a
|
||||
handy plugin called indent_, which handles indentation settings for Python source
|
||||
files.
|
||||
handy plugin called indent_, which handles indentation settings for Python
|
||||
source files.
|
||||
|
||||
There is also a handy syntax plugin called syntax_ featuring some improvements over
|
||||
the syntax file included in Vim 6.1.
|
||||
There is also a handy syntax plugin called syntax_ featuring some improvements
|
||||
over the syntax file included in Vim 6.1.
|
||||
|
||||
These plugins supply you with a basic environment for developing in Python.
|
||||
To get the most out of Vim, you should continually check your code for syntax
|
||||
errors and PEP8 compliance. Luckily PEP8_ and Pyflakes_ will do this for you.
|
||||
If your Vim is compiled with :option:`+python` you can also utilize some very handy
|
||||
plugins to do these checks from within the editor.
|
||||
If your Vim is compiled with :option:`+python` you can also utilize some very
|
||||
handy plugins to do these checks from within the editor.
|
||||
|
||||
For PEP8 checking, install the vim-pep8_ plugin, and for pyflakes you can
|
||||
install vim-pyflakes_. Now you can map the functions ``Pep8()`` or ``Pyflakes()``
|
||||
to any hotkey or action you want in Vim. Both plugins will display errors at
|
||||
the bottom of the screen, and provide an easy way to jump to the corresponding
|
||||
line. It's very handy to call these functions whenever you save a file. In
|
||||
order to do this, add the following lines to your :file:`.vimrc`::
|
||||
install vim-pyflakes_. Now you can map the functions ``Pep8()`` or
|
||||
``Pyflakes()`` to any hotkey or action you want in Vim. Both plugins will
|
||||
display errors at the bottom of the screen, and provide an easy way to jump to
|
||||
the corresponding line. It's very handy to call these functions whenever you
|
||||
save a file. In order to do this, add the following lines to your
|
||||
:file:`.vimrc`::
|
||||
|
||||
autocmd BufWritePost *.py call Pyflakes()
|
||||
autocmd BufWritePost *.py call Pep8()
|
||||
|
||||
If you are already using syntastic_, you can set it to run Pyflakes on write
|
||||
and show errors and warnings in the quickfix window. An example configuration
|
||||
to do that which also shows status and warning messages in the statusbar would be::
|
||||
to do that which also shows status and warning messages in the statusbar would
|
||||
be::
|
||||
|
||||
set statusline+=%#warningmsg#
|
||||
set statusline+=%{SyntasticStatuslineFlag()}
|
||||
@@ -112,8 +114,8 @@ TextMate
|
||||
--------
|
||||
|
||||
`TextMate <http://macromates.com/>`_ brings Apple's approach to operating
|
||||
systems into the world of text editors. By bridging UNIX underpinnings and GUI,
|
||||
TextMate cherry-picks the best of both worlds to the benefit of expert
|
||||
systems into the world of text editors. By bridging UNIX underpinnings and
|
||||
GUI, TextMate cherry-picks the best of both worlds to the benefit of expert
|
||||
scripters and novice users alike.
|
||||
|
||||
Sublime Text
|
||||
@@ -124,18 +126,21 @@ Sublime Text
|
||||
extraordinary features and amazing performance.
|
||||
|
||||
Sublime Text has excellent support for editing Python code and uses Python for
|
||||
its plugin API. It also has a diverse variety of plugins, `some of which <https://github.com/SublimeLinter/SublimeLinter>`_
|
||||
allow for in-editor PEP8 checking and code "linting".
|
||||
its plugin API. It also has a diverse variety of plugins,
|
||||
`some of which <https://github.com/SublimeLinter/SublimeLinter>`_ allow for
|
||||
in-editor PEP8 checking and code "linting".
|
||||
|
||||
Atom
|
||||
----
|
||||
|
||||
`Atom <https://atom.io/>`_ is a hackable text editor for the 21st century,
|
||||
built on atom-shell, and based on everything we love about our favorite editors.
|
||||
built on atom-shell, and based on everything we love about our favorite
|
||||
editors.
|
||||
|
||||
Atom is web native (HTML, CSS, JS), focusing on modular design and easy plugin development.
|
||||
It comes with native package control and plethora of packages. Recommended for Python
|
||||
development is `Linter <https://github.com/AtomLinter/Linter>`_ combined with
|
||||
Atom is web native (HTML, CSS, JS), focusing on modular design and easy plugin
|
||||
development. It comes with native package control and plethora of packages.
|
||||
Recommended for Python development is
|
||||
`Linter <https://github.com/AtomLinter/Linter>`_ combined with
|
||||
`linter-flake8 <https://github.com/AtomLinter/linter-flake8>`_.
|
||||
|
||||
|
||||
@@ -147,9 +152,10 @@ PyCharm / IntelliJ IDEA
|
||||
|
||||
`PyCharm <http://www.jetbrains.com/pycharm/>`_ is developed by JetBrains, also
|
||||
known for IntelliJ IDEA. Both share the same code base and most of PyCharm's
|
||||
features can be brought to IntelliJ with the free `Python Plug-In <http://plugins.intellij.net/plugin/?id=631>`_.
|
||||
There are two versions of PyCharm: Professional Edition (Free 30-day trial)
|
||||
and Community Edition(Apache 2.0 License) with fewer features.
|
||||
features can be brought to IntelliJ with the free
|
||||
`Python Plug-In <http://plugins.intellij.net/plugin/?id=631>`_. There are two
|
||||
versions of PyCharm: Professional Edition (Free 30-day trial) and Community
|
||||
Edition(Apache 2.0 License) with fewer features.
|
||||
|
||||
|
||||
Eclipse
|
||||
@@ -172,9 +178,10 @@ Spyder
|
||||
------
|
||||
|
||||
`Spyder <http://code.google.com/p/spyderlib/>`_ is an IDE specifically geared
|
||||
toward working with scientific Python libraries (namely `Scipy <http://www.scipy.org/>`_).
|
||||
It includes integration with pyflakes_, `pylint <http://www.logilab.org/857>`_
|
||||
and `rope <http://rope.sourceforge.net/>`_.
|
||||
toward working with scientific Python libraries (namely
|
||||
`Scipy <http://www.scipy.org/>`_). It includes integration with pyflakes_,
|
||||
`pylint <http://www.logilab.org/857>`_ and
|
||||
`rope <http://rope.sourceforge.net/>`_.
|
||||
|
||||
Spyder is open-source (free), offers code completion, syntax highlighting,
|
||||
a class and function browser, and object inspection.
|
||||
@@ -195,11 +202,13 @@ NINJA-IDE
|
||||
|
||||
`NINJA-IDE <http://www.ninja-ide.org/>`_ (from the recursive acronym: "Ninja-IDE
|
||||
Is Not Just Another IDE") is a cross-platform IDE, specially designed to build
|
||||
Python applications, and runs on Linux/X11, Mac OS X and Windows desktop operating
|
||||
systems. Installers for these platforms can be downloaded from the website.
|
||||
Python applications, and runs on Linux/X11, Mac OS X and Windows desktop
|
||||
operating systems. Installers for these platforms can be downloaded from the
|
||||
website.
|
||||
|
||||
NINJA-IDE is open-source software (GPLv3 licence) and is developed in Python and
|
||||
Qt. The source files can be downloaded from `GitHub <https://github.com/ninja-ide>`_.
|
||||
NINJA-IDE is open-source software (GPLv3 licence) and is developed
|
||||
in Python and Qt. The source files can be downloaded from
|
||||
`GitHub <https://github.com/ninja-ide>`_.
|
||||
|
||||
|
||||
Eric (The Eric Python IDE)
|
||||
@@ -210,8 +219,8 @@ offering sourcecode autocompletion, syntax highlighting, support for version
|
||||
control systems, python 3 support, integrated web browser, python shell,
|
||||
integrated debugger and a flexible plug-in system. Written in python, it is
|
||||
based on the Qt gui toolkit, integrating the Scintilla editor control. Eric
|
||||
is an open-source software project (GPLv3 licence) with more than ten years of active
|
||||
development.
|
||||
is an open-source software project (GPLv3 licence) with more than ten years of
|
||||
active development.
|
||||
|
||||
|
||||
Interpreter Tools
|
||||
@@ -221,15 +230,16 @@ Interpreter Tools
|
||||
Virtual Environments
|
||||
--------------------
|
||||
|
||||
A Virtual Environment is a tool to keep the dependencies required by different projects
|
||||
in separate places, by creating virtual Python environments for them. It solves the
|
||||
"Project X depends on version 1.x but, Project Y needs 4.x" dilemma, and keeps
|
||||
your global site-packages directory clean and manageable.
|
||||
A Virtual Environment is a tool to keep the dependencies required by different
|
||||
projects in separate places, by creating virtual Python environments for them.
|
||||
It solves the "Project X depends on version 1.x but, Project Y needs 4.x"
|
||||
dilemma, and keeps your global site-packages directory clean and manageable.
|
||||
|
||||
For example, you can work on a project which requires Django 1.3 while also
|
||||
maintaining a project which requires Django 1.0.
|
||||
|
||||
To start using and see more information: `Virtual Environments <http://github.com/kennethreitz/python-guide/blob/master/docs/dev/virtualenvs.rst>`_ docs.
|
||||
To start using and see more information:
|
||||
`Virtual Environments <http://github.com/kennethreitz/python-guide/blob/master/docs/dev/virtualenvs.rst>`_ docs.
|
||||
|
||||
Other Tools
|
||||
:::::::::::
|
||||
@@ -273,7 +283,8 @@ BPython
|
||||
-------
|
||||
|
||||
`bpython <http://bpython-interpreter.org/>`_ is an alternative interface to the
|
||||
Python interpreter for Unix-like operating systems. It has the following features:
|
||||
Python interpreter for Unix-like operating systems. It has the following
|
||||
features:
|
||||
|
||||
* In-line syntax highlighting.
|
||||
* Readline-like autocomplete with suggestions displayed as you type.
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
Virtual Environments
|
||||
====================
|
||||
|
||||
A Virtual Environment is a tool to keep the dependencies required by different projects
|
||||
in separate places, by creating virtual Python environments for them. It solves the
|
||||
"Project X depends on version 1.x but, Project Y needs 4.x" dilemma, and keeps
|
||||
your global site-packages directory clean and manageable.
|
||||
A Virtual Environment is a tool to keep the dependencies required by different
|
||||
projects in separate places, by creating virtual Python environments for them.
|
||||
It solves the "Project X depends on version 1.x but, Project Y needs 4.x"
|
||||
dilemma, and keeps your global site-packages directory clean and manageable.
|
||||
|
||||
For example, you can work on a project which requires Django 1.3 while also
|
||||
maintaining a project which requires Django 1.0.
|
||||
@@ -32,10 +32,11 @@ Basic Usage
|
||||
$ cd my_project_folder
|
||||
$ virtualenv venv
|
||||
|
||||
``virtualenv venv`` will create a folder in the current directory which will contain
|
||||
the Python executable files, and a copy of the ``pip`` library which you can use to
|
||||
install other packages. The name of the virtual environment (in this case, it was ``venv``)
|
||||
can be anything; omitting the name will place the files in the current directory instead.
|
||||
``virtualenv venv`` will create a folder in the current directory which will
|
||||
contain the Python executable files, and a copy of the ``pip`` library which you
|
||||
can use to install other packages. The name of the virtual environment (in this
|
||||
case, it was ``venv``) can be anything; omitting the name will place the files
|
||||
in the current directory instead.
|
||||
|
||||
This creates a copy of Python in whichever directory you ran the command in,
|
||||
placing it in a folder named :file:`venv`.
|
||||
|
||||
@@ -84,4 +84,5 @@ first-time Pythonista, and the authors to the Guide will gladly help if you
|
||||
have any questions about the appropriateness, completeness, or accuracy of
|
||||
a contribution.
|
||||
|
||||
To get started working on The Hitchhiker's Guide, see the :doc:`/notes/contribute` page.
|
||||
To get started working on The Hitchhiker's Guide,
|
||||
see the :doc:`/notes/contribute` page.
|
||||
|
||||
+38
-35
@@ -7,9 +7,9 @@ Beginner
|
||||
The Python Tutorial
|
||||
~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is the official tutorial. It covers all the basics, and offers a tour of the
|
||||
language and the standard library. Recommended for those who need a quickstart
|
||||
guide to the language.
|
||||
This is the official tutorial. It covers all the basics, and offers a tour of
|
||||
the language and the standard library. Recommended for those who need a
|
||||
quickstart guide to the language.
|
||||
|
||||
`The Python Tutorial <http://docs.python.org/tutorial/index.html>`_
|
||||
|
||||
@@ -18,15 +18,16 @@ Learn Python Interactive Tutorial
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Learnpython.org is an easy non-intimidating way to get introduced to Python.
|
||||
The website takes the same approach used on the popular `Try Ruby <http://tryruby.org/>`_
|
||||
website, it has an interactive Python interpreter built into the site that
|
||||
allows you to go through the lessons without having to install Python locally.
|
||||
The website takes the same approach used on the popular
|
||||
`Try Ruby <http://tryruby.org/>`_ website, it has an interactive Python
|
||||
interpreter built into the site that allows you to go through the lessons
|
||||
without having to install Python locally.
|
||||
|
||||
`Learn Python <http://www.learnpython.org/>`_
|
||||
|
||||
|
||||
If you want a more traditional book, *Python For You and Me* is an
|
||||
excellent resource for learning all aspects of the language.
|
||||
If you want a more traditional book, *Python For You and Me* is an excellent
|
||||
resource for learning all aspects of the language.
|
||||
|
||||
`Python for You and Me <http://pymbook.readthedocs.org/>`_
|
||||
|
||||
@@ -121,8 +122,8 @@ More information about test driven development can be found at these resources:
|
||||
A Byte of Python
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
A free introductory book that teaches Python at the beginner level, it assumes no
|
||||
previous programming experience.
|
||||
A free introductory book that teaches Python at the beginner level, it assumes
|
||||
no previous programming experience.
|
||||
|
||||
`A Byte of Python for Python 2.x <http://www.ibiblio.org/swaroopch/byteofpython/read/>`_
|
||||
`A Byte of Python for Python 3.x <http://swaroopch.com/notes/Python_en-Preface/>`_
|
||||
@@ -142,8 +143,9 @@ Advanced
|
||||
Pro Python
|
||||
~~~~~~~~~~
|
||||
|
||||
This book is for intermediate to advanced Python programmers who are looking to understand how
|
||||
and why Python works the way it does and how they can take their code to the next level.
|
||||
This book is for intermediate to advanced Python programmers who are looking to
|
||||
understand how and why Python works the way it does and how they can take their
|
||||
code to the next level.
|
||||
|
||||
`Pro Python <http://propython.com>`_
|
||||
|
||||
@@ -169,8 +171,8 @@ A Guide to Python's Magic Methods
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is a collection of blog posts by Rafe Kettler which explain 'magic methods'
|
||||
in Python. Magic methods are surrounded by double underscores (i.e. __init__) and
|
||||
can make classes and objects behave in different and magical ways.
|
||||
in Python. Magic methods are surrounded by double underscores (i.e. __init__)
|
||||
and can make classes and objects behave in different and magical ways.
|
||||
|
||||
`A Guide to Python's Magic Methods <http://www.rafekettler.com/magicmethods.html>`_
|
||||
|
||||
@@ -181,17 +183,17 @@ For Engineers and Scientists
|
||||
A Primer on Scientific Programming with Python
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
A Primer on Scientific Programming with Python, written by Hans Petter Langtangen,
|
||||
mainly covers Python's usage in the scientific field. In the book, examples are
|
||||
chosen from mathematics and the natural sciences.
|
||||
A Primer on Scientific Programming with Python, written by Hans Petter
|
||||
Langtangen, mainly covers Python's usage in the scientific field. In the book,
|
||||
examples are chosen from mathematics and the natural sciences.
|
||||
|
||||
`A Primer on Scientific Programming with Python <http://www.springer.com/mathematics/computational+science+%26+engineering/book/978-3-642-30292-3>`_
|
||||
|
||||
Numerical Methods in Engineering with Python
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Numerical Methods in Engineering with Python, written by Jaan Kiusalaas, puts the
|
||||
emphasis on numerical methods and how to implement them in Python.
|
||||
Numerical Methods in Engineering with Python, written by Jaan Kiusalaas,
|
||||
puts the emphasis on numerical methods and how to implement them in Python.
|
||||
|
||||
`Numerical Methods in Engineering with Python <http://www.cambridge.org/us/academic/subjects/engineering/engineering-mathematics-and-programming/numerical-methods-engineering-python-2nd-edition>`_
|
||||
|
||||
@@ -201,9 +203,9 @@ Miscellaneous topics
|
||||
Problem Solving with Algorithms and Data Structures
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Problem Solving with Algorithms and Data Structures covers a range of data structures and
|
||||
algorithms. All concepts are illustrated with Python code along with interactive samples
|
||||
that can be run directly in the browser.
|
||||
Problem Solving with Algorithms and Data Structures covers a range of data
|
||||
structures and algorithms. All concepts are illustrated with Python code along
|
||||
with interactive samples that can be run directly in the browser.
|
||||
|
||||
`Problem Solving with Algorithms and Data Structures
|
||||
<http://www.interactivepython.org/courselib/static/pythonds/index.html>`_
|
||||
@@ -211,9 +213,10 @@ that can be run directly in the browser.
|
||||
Programming Collective Intelligence
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Programming Collective Intelligence introduces a wide array of basic machine learning and
|
||||
data mining methods. The exposition is not very mathematically formal, but rather focuses
|
||||
on explaining the underlying intuition and shows how to implement the algorithms in Python.
|
||||
Programming Collective Intelligence introduces a wide array of basic machine
|
||||
learning and data mining methods. The exposition is not very mathematically
|
||||
formal, but rather focuses on explaining the underlying intuition and shows
|
||||
how to implement the algorithms in Python.
|
||||
|
||||
`Programming Collective Intelligence <http://shop.oreilly.com/product/9780596529321.do>`_
|
||||
|
||||
@@ -232,17 +235,17 @@ as writing C extensions.
|
||||
The Python Language Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
This is Python's reference manual, it covers the syntax and the core semantics of the
|
||||
language.
|
||||
This is Python's reference manual, it covers the syntax and the core semantics
|
||||
of the language.
|
||||
|
||||
`The Python Language Reference <http://docs.python.org/reference/index.html>`_
|
||||
|
||||
Python Pocket Reference
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Python Pocket Reference, written by Mark Lutz, is an easy to use reference to the
|
||||
core language, with descriptions of commonly used modules and toolkits. It covers
|
||||
Python 3 and 2.6 versions.
|
||||
Python Pocket Reference, written by Mark Lutz, is an easy to use reference to
|
||||
the core language, with descriptions of commonly used modules and toolkits. It
|
||||
covers Python 3 and 2.6 versions.
|
||||
|
||||
`Python Pocket Reference <http://shop.oreilly.com/product/9780596158095.do>`_
|
||||
|
||||
@@ -259,11 +262,11 @@ Writing Idiomatic Python
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
"Writing Idiomatic Python", written by Jeff Knupp, contains the most common and
|
||||
important Python idioms in a format that maximizes identification and understanding.
|
||||
Each idiom is presented as a recommendation of a way to write some commonly
|
||||
used piece of code, followed by an explanation of why the idiom is important.
|
||||
It also contains two code samples for each idiom: the "Harmful" way to write it
|
||||
and the "Idiomatic" way.
|
||||
important Python idioms in a format that maximizes identification and
|
||||
understanding. Each idiom is presented as a recommendation of a way to write
|
||||
some commonly used piece of code, followed by an explanation of why the idiom
|
||||
is important. It also contains two code samples for each idiom: the "Harmful"
|
||||
way to write it and the "Idiomatic" way.
|
||||
|
||||
`For Python 2.7.3+ <http://www.amazon.com/Writing-Idiomatic-Python-2-7-3-Knupp/dp/1482372177/>`_
|
||||
|
||||
|
||||
+4
-4
@@ -35,15 +35,15 @@ new releases, jobs, etc. related to Python.
|
||||
Python News
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
Python News is the news section in the official Python web site (www.python.org). It briefly
|
||||
highlights the news from the Python community.
|
||||
Python News is the news section in the official Python web site
|
||||
(www.python.org). It briefly highlights the news from the Python community.
|
||||
|
||||
`Python News <http://www.python.org/news/>`_
|
||||
|
||||
Import Python Weekly
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
Weekly Python Newsletter containing Python Articles, Projects, Videos, Tweets delivered in your inbox.
|
||||
Keep Your Python Programming Skills Updated.
|
||||
Weekly Python Newsletter containing Python Articles, Projects, Videos, Tweets
|
||||
delivered in your inbox. Keep Your Python Programming Skills Updated.
|
||||
|
||||
`Import Python Weekly Newsletter <http://www.importpython.com/newsletter/>`_
|
||||
|
||||
+49
-42
@@ -38,8 +38,8 @@ server.
|
||||
run('git pull')
|
||||
run('touch app.wsgi')
|
||||
|
||||
With the previous code saved in a file named :file:`fabfile.py`, we can check memory
|
||||
usage with:
|
||||
With the previous code saved in a file named :file:`fabfile.py`, we can check
|
||||
memory usage with:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -72,10 +72,10 @@ programs, and host grouping.
|
||||
Salt
|
||||
----
|
||||
|
||||
`Salt <http://saltstack.org/>`_ is an open source infrastructure management tool.
|
||||
It supports remote command execution from a central point (master host) to multiple
|
||||
hosts (minions). It also supports system states which can be used to configure
|
||||
multiple servers using simple template files.
|
||||
`Salt <http://saltstack.org/>`_ is an open source infrastructure management
|
||||
tool. It supports remote command execution from a central point (master host)
|
||||
to multiple hosts (minions). It also supports system states which can be used
|
||||
to configure multiple servers using simple template files.
|
||||
|
||||
Salt supports Python versions 2.6 and 2.7 and can be installed via pip:
|
||||
|
||||
@@ -83,8 +83,9 @@ Salt supports Python versions 2.6 and 2.7 and can be installed via pip:
|
||||
|
||||
$ pip install salt
|
||||
|
||||
After configuring a master server and any number of minion hosts, we can run arbitrary
|
||||
shell commands or use pre-built modules of complex commands on our minions.
|
||||
After configuring a master server and any number of minion hosts, we can run
|
||||
arbitrary shell commands or use pre-built modules of complex commands on our
|
||||
minions.
|
||||
|
||||
The following command lists all available minion hosts, using the ping module.
|
||||
|
||||
@@ -92,21 +93,24 @@ The following command lists all available minion hosts, using the ping module.
|
||||
|
||||
$ salt '*' test.ping
|
||||
|
||||
The host filtering is accomplished by matching the minion id, or using the grains system.
|
||||
The `grains <http://docs.saltstack.org/en/latest/topics/targeting/grains.html>`_ system
|
||||
uses static host information like the operating system version or the CPU architecture to
|
||||
provide a host taxonomy for the Salt modules.
|
||||
The host filtering is accomplished by matching the minion id,
|
||||
or using the grains system. The
|
||||
`grains <http://docs.saltstack.org/en/latest/topics/targeting/grains.html>`_
|
||||
system uses static host information like the operating system version or the
|
||||
CPU architecture to provide a host taxonomy for the Salt modules.
|
||||
|
||||
The following command lists all available minions running CentOS using the grains system:
|
||||
The following command lists all available minions running CentOS using the
|
||||
grains system:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ salt -G 'os:CentOS' test.ping
|
||||
|
||||
Salt also provides a state system. States can be used to configure the minion hosts.
|
||||
Salt also provides a state system. States can be used to configure the minion
|
||||
hosts.
|
||||
|
||||
For example, when a minion host is ordered to read the following state file, it will install
|
||||
and start the Apache server:
|
||||
For example, when a minion host is ordered to read the following state file,
|
||||
it will install and start the Apache server:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
@@ -241,28 +245,29 @@ Puppet
|
||||
------
|
||||
|
||||
`Puppet <http://puppetlabs.com>`_ is IT Automation and configuration management
|
||||
software from Puppet Labs that allows System Administrators to define the state of
|
||||
their IT Infrastructure, thereby providing an elegant way to manage their fleet of
|
||||
physical and virtual machines.
|
||||
software from Puppet Labs that allows System Administrators to define the state
|
||||
of their IT Infrastructure, thereby providing an elegant way to manage their
|
||||
fleet of physical and virtual machines.
|
||||
|
||||
Puppet is available both as an Open Source and an Enterprise variant. Modules are
|
||||
small, shareable units of code written to automate or define the state of a system.
|
||||
`Puppet Forge <https://forge.puppetlabs.com/>`_ is a repository for modules written
|
||||
by the community for Open Source and Enterprise Puppet.
|
||||
Puppet is available both as an Open Source and an Enterprise variant. Modules
|
||||
are small, shareable units of code written to automate or define the state of a
|
||||
system. `Puppet Forge <https://forge.puppetlabs.com/>`_ is a repository for
|
||||
modules written by the community for Open Source and Enterprise Puppet.
|
||||
|
||||
Puppet Agents are installed on nodes whose state needs to be monitored or changed.
|
||||
A desginated server known as the Puppet Master is responsible for orchastrating the
|
||||
agent nodes.
|
||||
Puppet Agents are installed on nodes whose state needs to be monitored or
|
||||
changed. A desginated server known as the Puppet Master is responsible for
|
||||
orchastrating the agent nodes.
|
||||
|
||||
Agent nodes send basic facts about the system such as to the operating system, kernel,
|
||||
architecture, ip address, hostname etc. to the Puppet Master.
|
||||
The Puppet Master then compiles a catalog with information provided by the agents on
|
||||
how each node should be configured and sends it to the agent. The agent enforces the
|
||||
change as prescribed in the catalog and sends a report back to the Puppet Master.
|
||||
Agent nodes send basic facts about the system such as to the operating system,
|
||||
kernel, architecture, ip address, hostname etc. to the Puppet Master.
|
||||
The Puppet Master then compiles a catalog with information provided by the
|
||||
agents on how each node should be configured and sends it to the agent. The
|
||||
agent enforces the change as prescribed in the catalog and sends a report back
|
||||
to the Puppet Master.
|
||||
|
||||
Facter is an interesting tool that ships with Puppet that pulls basic facts about
|
||||
the system. These facts can be referenced as a variable while writing your
|
||||
Puppet modules.
|
||||
Facter is an interesting tool that ships with Puppet that pulls basic facts
|
||||
about the system. These facts can be referenced as a variable while writing
|
||||
your Puppet modules.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -273,8 +278,8 @@ Puppet modules.
|
||||
$ facter operatingsystem
|
||||
Ubuntu
|
||||
|
||||
Writing Modules in Puppet is pretty straight forward. Puppet Manifests together form
|
||||
Puppet Modules. Puppet manifest end with an extension of ``.pp``.
|
||||
Writing Modules in Puppet is pretty straight forward. Puppet Manifests together
|
||||
form Puppet Modules. Puppet manifest end with an extension of ``.pp``.
|
||||
Here is an example of 'Hello World' in Puppet.
|
||||
|
||||
.. code-block:: puppet
|
||||
@@ -285,9 +290,10 @@ Here is an example of 'Hello World' in Puppet.
|
||||
#the notification message by default.
|
||||
}
|
||||
|
||||
Here is another example with system based logic. Note how the operatingsystem fact
|
||||
is being used as a variable prepended with the ``$`` sign. Similarly, this holds true
|
||||
for other facts such as hostname which can be referenced by ``$hostname``
|
||||
Here is another example with system based logic. Note how the operatingsystem
|
||||
fact is being used as a variable prepended with the ``$`` sign. Similarly, this
|
||||
holds true for other facts such as hostname which can be referenced by
|
||||
``$hostname``
|
||||
|
||||
.. code-block:: puppet
|
||||
|
||||
@@ -298,9 +304,10 @@ for other facts such as hostname which can be referenced by ``$hostname``
|
||||
},
|
||||
}
|
||||
|
||||
There are several resource types for Puppet but the package-file-service paradigm is all
|
||||
you need for undertaking majority of the configuration management. The following Puppet code makes sure
|
||||
that the OpenSSH-Server package is installed in a system and the sshd service is notified to restart
|
||||
There are several resource types for Puppet but the package-file-service
|
||||
paradigm is all you need for undertaking majority of the configuration
|
||||
management. The following Puppet code makes sure that the OpenSSH-Server
|
||||
package is installed in a system and the sshd service is notified to restart
|
||||
everytime the sshd configuration file is changed.
|
||||
|
||||
.. code-block:: puppet
|
||||
|
||||
@@ -62,15 +62,15 @@ which provides the following features:
|
||||
Travis-CI
|
||||
---------
|
||||
|
||||
`Travis-CI <https://travis-ci.org/>`_ is a distributed CI server which builds tests
|
||||
for open source projects for free. It provides multiple workers to run Python tests
|
||||
on and seamlessly integrates with GitHub. You can even have it comment on your Pull
|
||||
Requests whether this particular changeset breaks the build or not. So if you are
|
||||
hosting your code on GitHub, travis-ci is a great and easy way to get started with
|
||||
Continuous Integration.
|
||||
`Travis-CI <https://travis-ci.org/>`_ is a distributed CI server which builds
|
||||
tests for open source projects for free. It provides multiple workers to run
|
||||
Python tests on and seamlessly integrates with GitHub. You can even have it
|
||||
comment on your Pull Requests whether this particular changeset breaks the
|
||||
build or not. So if you are hosting your code on GitHub, travis-ci is a great
|
||||
and easy way to get started with Continuous Integration.
|
||||
|
||||
In order to get started, add a :file:`.travis.yml` file to your repository with this
|
||||
example content::
|
||||
In order to get started, add a :file:`.travis.yml` file to your repository with
|
||||
this example content::
|
||||
|
||||
language: python
|
||||
python:
|
||||
|
||||
@@ -45,10 +45,11 @@ library is designed to have a familiar socket-style API.
|
||||
RabbitMQ
|
||||
--------
|
||||
|
||||
RabbitMQ is an open source message broker software that implements the Advanced Message Queuing Protocol (AMQP).
|
||||
The RabbitMQ server is written in the Erlang programming language and is built on the Open Telecom Platform
|
||||
framework for clustering and failover. Client libraries to interface with the broker are available
|
||||
for all major programming languages.
|
||||
RabbitMQ is an open source message broker software that implements the Advanced
|
||||
Message Queuing Protocol (AMQP). The RabbitMQ server is written in the Erlang
|
||||
programming language and is built on the Open Telecom Platform framework for
|
||||
clustering and failover. Client libraries to interface with the broker are
|
||||
available for all major programming languages.
|
||||
|
||||
- `Homepage <http://www.rabbitmq.com/>`_
|
||||
- `GitHub Organization <https://github.com/rabbitmq?page=1>`_
|
||||
|
||||
@@ -9,9 +9,9 @@ library that provides cryptographic recipes and primitives. It supports
|
||||
Python 2.6-2.7, Python 3.2+ and PyPy.
|
||||
|
||||
|
||||
Cryptography is divided into two layers of recipes and hazardous materials (hazmat).
|
||||
The recipes layer provides simple API for proper symmetric encryption and the
|
||||
hazmat layer provides low-level cryptographic primitives.
|
||||
Cryptography is divided into two layers of recipes and hazardous materials
|
||||
(hazmat). The recipes layer provides simple API for proper symmetric
|
||||
encryption and the hazmat layer provides low-level cryptographic primitives.
|
||||
|
||||
|
||||
|
||||
|
||||
+21
-13
@@ -30,39 +30,47 @@ Django ORM
|
||||
The Django ORM is the interface used by `Django <http://www.djangoproject.com>`_
|
||||
to provide database access.
|
||||
|
||||
It's based on the idea of `models <https://docs.djangoproject.com/en/1.3/#the-model-layer>`_,
|
||||
It's based on the idea of
|
||||
`models <https://docs.djangoproject.com/en/1.3/#the-model-layer>`_,
|
||||
an abstraction that makes it easier to manipulate data in Python.
|
||||
|
||||
The basics:
|
||||
|
||||
- Each model is a Python class that subclasses django.db.models.Model.
|
||||
- Each attribute of the model represents a database field.
|
||||
- Django gives you an automatically-generated database-access API; see `Making queries <https://docs.djangoproject.com/en/dev/topics/db/queries/>`__.
|
||||
- Django gives you an automatically-generated database-access API; see
|
||||
`Making queries <https://docs.djangoproject.com/en/dev/topics/db/queries/>`__.
|
||||
|
||||
peewee
|
||||
------
|
||||
|
||||
`peewee <http://docs.peewee-orm.com/en/latest/>`_ is another ORM with a focus on being lightweight with support for
|
||||
Python 2.6+ and 3.2+ which supports SQLite, MySQL and Postgres by default. The `model layer <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#model-definition>`_
|
||||
is similar to that of the Django ORM and it has `SQL-like methods <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#retrieving-data>`_
|
||||
to query data. While SQLite, MySQL and Postgres are supported out-of-the-box, there is a `collection of add-ons <https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#playhouse>`_
|
||||
`peewee <http://docs.peewee-orm.com/en/latest/>`_ is another ORM with a focus
|
||||
on being lightweight with support for Python 2.6+ and 3.2+ which supports
|
||||
SQLite, MySQL and Postgres by default. The
|
||||
`model layer <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#model-definition>`_
|
||||
is similar to that of the Django ORM and it has
|
||||
`SQL-like methods <https://peewee.readthedocs.org/en/latest/peewee/quickstart.html#retrieving-data>`_
|
||||
to query data. While SQLite, MySQL and Postgres are supported out-of-the-box,
|
||||
there is a `collection of add-ons <https://peewee.readthedocs.org/en/latest/peewee/playhouse.html#playhouse>`_
|
||||
available.
|
||||
|
||||
PonyORM
|
||||
-------
|
||||
|
||||
`PonyORM <http://ponyorm.com/>`_ is an ORM that takes a different approach to querying the database. Instead of writing
|
||||
an SQL-like language or boolean expressions, Python's generator syntax is used. There's also an graphical schema editor
|
||||
that can generate PonyORM entities for you. It supports Python 2.6+ and Python 3.3+ and can connect to SQLite, MySQL,
|
||||
Postgres & Oracle
|
||||
`PonyORM <http://ponyorm.com/>`_ is an ORM that takes a different approach to
|
||||
querying the database. Instead of writing an SQL-like language or boolean
|
||||
expressions, Python's generator syntax is used. There's also an graphical
|
||||
schema editor that can generate PonyORM entities for you. It supports Python
|
||||
2.6+ and Python 3.3+ and can connect to SQLite, MySQL, Postgres & Oracle
|
||||
|
||||
|
||||
|
||||
SQLObject
|
||||
---------
|
||||
|
||||
`SQLObject <http://www.sqlobject.org/>`_ is yet another ORM. It supports a wide variety of databases: Common database systems
|
||||
MySQL, Postgres and SQLite and more exotic systems like SAP DB, SyBase and MSSQL. It only supports Python 2 from
|
||||
Python 2.6 upwards.
|
||||
`SQLObject <http://www.sqlobject.org/>`_ is yet another ORM. It supports a wide
|
||||
variety of databases: Common database systems MySQL, Postgres and SQLite and
|
||||
more exotic systems like SAP DB, SyBase and MSSQL. It only supports Python 2
|
||||
from Python 2.6 upwards.
|
||||
|
||||
.. There's no official information on this on their page, this information was gathered by looking at their source code
|
||||
|
||||
@@ -22,8 +22,8 @@ GTk
|
||||
PyGTK provides Python bindings for the GTK+ toolkit. Like the GTK+ library
|
||||
itself, it is currently licensed under the GNU LGPL. It is worth noting that
|
||||
PyGTK only currently supports the Gtk-2.X API (NOT Gtk-3.0). It is currently
|
||||
recommended that PyGTK not be used for new projects and that existing applications
|
||||
be ported from PyGTK to PyGObject.
|
||||
recommended that PyGTK not be used for new projects and that existing
|
||||
applications be ported from PyGTK to PyGObject.
|
||||
|
||||
Kivy
|
||||
----
|
||||
@@ -33,7 +33,8 @@ interaction design and rapid prototyping, while making your code reusable
|
||||
and deployable.
|
||||
|
||||
Kivy is written in Python, based on OpenGL and supports different input devices
|
||||
such as: Mouse, Dual Mouse, TUIO, WiiMote, WM_TOUCH, HIDtouch, Apple's products and so on.
|
||||
such as: Mouse, Dual Mouse, TUIO, WiiMote, WM_TOUCH, HIDtouch, Apple's products
|
||||
and so on.
|
||||
|
||||
Kivy is actively being developed by a community and is free to use. It operates
|
||||
on all major platforms (Linux, OSX, Windows, Android).
|
||||
@@ -62,8 +63,8 @@ PyjamasDesktop (pyjs Desktop)
|
||||
-----------------------------
|
||||
PyjamasDesktop is a port of Pyjamas. PyjamasDesktop is application widget set
|
||||
for desktop and a cross-platform framework. (After release v0.6 PyjamasDesktop
|
||||
is a part of Pyjamas (Pyjs)). Briefly, it allows the exact same Python web application
|
||||
source code to be executed as a standalone desktop application.
|
||||
is a part of Pyjamas (Pyjs)). Briefly, it allows the exact same Python web
|
||||
application source code to be executed as a standalone desktop application.
|
||||
|
||||
`Python Wiki for PyjamasDesktop <http://wiki.python.org/moin/PyjamasDesktop>`_.
|
||||
|
||||
|
||||
@@ -9,17 +9,19 @@ Python Imaging Library
|
||||
----------------------
|
||||
|
||||
The `Python Imaging Library <http://www.pythonware.com/products/pil/>`_, or PIL
|
||||
for short, is *the* library for image manipulation in Python. Unfortunately, its
|
||||
development has stagnated, with its last release in 2009.
|
||||
for short, is *the* library for image manipulation in Python. Unfortunately,
|
||||
its development has stagnated, with its last release in 2009.
|
||||
|
||||
Luckily for you, there's an actively-developed fork of PIL called `Pillow <http://python-pillow.github.io/>`_ -
|
||||
it's easier to install, runs on all operating systems, and supports Python 3.
|
||||
Luckily for you, there's an actively-developed fork of PIL called
|
||||
`Pillow <http://python-pillow.github.io/>`_ - it's easier to install, runs on
|
||||
all operating systems, and supports Python 3.
|
||||
|
||||
Installation
|
||||
~~~~~~~~~~~~
|
||||
|
||||
Before installing Pillow, you'll have to install Pillow's prerequisites. Find
|
||||
the instructions for your platform `here <https://pypi.python.org/pypi/Pillow/2.1.0#platform-specific-instructions>`_.
|
||||
the instructions for your platform
|
||||
`here <https://pypi.python.org/pypi/Pillow/2.1.0#platform-specific-instructions>`_.
|
||||
|
||||
After that, it's straightforward:
|
||||
|
||||
|
||||
+14
-5
@@ -1,7 +1,9 @@
|
||||
JSON
|
||||
====
|
||||
|
||||
The `json <https://docs.python.org/2/library/json.html>`_ library can parse JSON from strings or files. The library parses JSON into a Python dictionary or list. It can also convert Python dictionaries or lists into JSON strings.
|
||||
The `json <https://docs.python.org/2/library/json.html>`_ library can parse
|
||||
JSON from strings or files. The library parses JSON into a Python dictionary
|
||||
or list. It can also convert Python dictionaries or lists into JSON strings.
|
||||
|
||||
Parsing JSON
|
||||
------------
|
||||
@@ -43,14 +45,21 @@ You can also convert the following to JSON:
|
||||
simplejson
|
||||
----------
|
||||
|
||||
The JSON library was added to Python in version 2.6. If you're using an earlier version of Python, the `simplejson <https://simplejson.readthedocs.org/en/latest/>`_ library is available via PyPI.
|
||||
The JSON library was added to Python in version 2.6.
|
||||
If you're using an earlier version of Python, the
|
||||
`simplejson <https://simplejson.readthedocs.org/en/latest/>`_ library is
|
||||
available via PyPI.
|
||||
|
||||
simplejson mimics the json standard library. It is available so that developers that use older versions of Python can use the latest features available in the json lib.
|
||||
simplejson mimics the json standard library. It is available so that developers
|
||||
that use older versions of Python can use the latest features available in the
|
||||
json lib.
|
||||
|
||||
You can start using simplejson when the json library is not available by importing simplejson under a different name:
|
||||
You can start using simplejson when the json library is not available by
|
||||
importing simplejson under a different name:
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
import simplejson as json
|
||||
|
||||
After importing simplejson as json, the above examples will all work as if you were using the standard json library.
|
||||
After importing simplejson as json, the above examples will all work as if you
|
||||
were using the standard json library.
|
||||
|
||||
@@ -7,7 +7,8 @@ Twisted
|
||||
`Twisted <http://twistedmatrix.com/trac/>`_ is an event-driven networking
|
||||
engine. It can be used to build applications around many different networking
|
||||
protocols, including http servers and clients, applications using SMTP, POP3,
|
||||
IMAP or SSH protocols, instant messaging and `much more <http://twistedmatrix.com/trac/wiki/Documentation>`_.
|
||||
IMAP or SSH protocols, instant messaging
|
||||
and `much more <http://twistedmatrix.com/trac/wiki/Documentation>`_.
|
||||
|
||||
PyZMQ
|
||||
-----
|
||||
@@ -30,5 +31,6 @@ For a quick start, read the `ZeroMQ guide <http://zguide.zeromq.org/page:all>`_.
|
||||
gevent
|
||||
------
|
||||
|
||||
`gevent <http://www.gevent.org/>`_ is a coroutine-based Python networking library
|
||||
that uses greenlets to provide a high-level synchronous API on top of the libev event loop.
|
||||
`gevent <http://www.gevent.org/>`_ is a coroutine-based Python networking
|
||||
library that uses greenlets to provide a high-level synchronous API on top of
|
||||
the libev event loop.
|
||||
|
||||
@@ -95,9 +95,10 @@ Rpy2
|
||||
----
|
||||
|
||||
`Rpy2 <http://rpy.sourceforge.net/rpy2.html>`_ is a Python binding for the R
|
||||
statistical package allowing the execution of R functions from Python and passing
|
||||
data back and forth between the two environments. Rpy2 is the object oriented
|
||||
implementation of the `Rpy <http://rpy.sourceforge.net/rpy.html>`_ bindings.
|
||||
statistical package allowing the execution of R functions from Python and
|
||||
passing data back and forth between the two environments. Rpy2 is the object
|
||||
oriented implementation of the `Rpy <http://rpy.sourceforge.net/rpy.html>`_
|
||||
bindings.
|
||||
|
||||
PsychoPy
|
||||
--------
|
||||
@@ -121,11 +122,12 @@ Unofficial Windows Binaries for Python Extension Packages
|
||||
---------------------------------------------------------
|
||||
|
||||
Many people who do scientific computing are on Windows, yet many of the
|
||||
scientific computing packages are notoriously difficult to build and install
|
||||
on this platform. `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_
|
||||
however, has compiled a list of Windows binaries for many useful Python packages.
|
||||
The list of packages has grown from a mainly scientific Python resource to a more
|
||||
general list. If you're on Windows, you may want to check it out.
|
||||
scientific computing packages are notoriously difficult to build and install on
|
||||
this platform. `Christoph Gohlke <http://www.lfd.uci.edu/~gohlke/pythonlibs/>`_
|
||||
however, has compiled a list of Windows binaries for many useful Python
|
||||
packages. The list of packages has grown from a mainly scientific Python
|
||||
resource to a more general list. If you're on Windows, you may want to check it
|
||||
out.
|
||||
|
||||
Anaconda
|
||||
--------
|
||||
|
||||
@@ -19,9 +19,10 @@ lxml and Requests
|
||||
|
||||
`lxml <http://lxml.de/>`_ is a pretty extensive library written for parsing
|
||||
XML and HTML documents very quickly, even handling messed up tags in the
|
||||
process. We will also be using the `Requests <http://docs.python-requests.org/en/latest/>`_
|
||||
module instead of the already built-in urllib2 module due to improvements in speed and
|
||||
readability. You can easily install both using ``pip install lxml`` and
|
||||
process. We will also be using the
|
||||
`Requests <http://docs.python-requests.org/en/latest/>`_ module instead of the
|
||||
already built-in urllib2 module due to improvements in speed and readability.
|
||||
You can easily install both using ``pip install lxml`` and
|
||||
``pip install requests``.
|
||||
|
||||
Let's start with the imports:
|
||||
|
||||
+22
-23
@@ -92,9 +92,10 @@ Support can be found on its `mailing list <http://werkzeug.pocoo.org/community/#
|
||||
|
||||
Tornado
|
||||
--------
|
||||
`Tornado <http://www.tornadoweb.org/>`_ is a scalable, non-blocking web server and web application framework with
|
||||
a relative simple usage. Tornado is known for its high performance.
|
||||
It was initially developed for `friendfeed <http://friendfeed.com/>`_ , a real time chat and blog system.
|
||||
`Tornado <http://www.tornadoweb.org/>`_ is a scalable, non-blocking web server
|
||||
and web application framework with a relative simple usage. Tornado is known
|
||||
for its high performance. It was initially developed for
|
||||
`friendfeed <http://friendfeed.com/>`_ , a real time chat and blog system.
|
||||
|
||||
In the Jinja2 template engine example it is used to serve the rendered pages.
|
||||
|
||||
@@ -108,9 +109,9 @@ and functionality and can thus not be considered lightweight. On the other
|
||||
hand, it does not provide all the functionality Django does. Instead Pyramid
|
||||
brings basic support for most regular tasks and provides a great deal of
|
||||
extensibility. Additionally, Pyramid has a huge focus on complete
|
||||
`documentation <http://docs.pylonsproject.org/en/latest/docs/pyramid.html>`__. As
|
||||
a little extra it comes with the Werkzeug Debugger which allows you to debug a
|
||||
running web application in the browser.
|
||||
`documentation <http://docs.pylonsproject.org/en/latest/docs/pyramid.html>`__.
|
||||
As a little extra it comes with the Werkzeug Debugger which allows you to debug
|
||||
a running web application in the browser.
|
||||
|
||||
**Support** can also be found in the
|
||||
`documentation <http://docs.pylonsproject.org/en/latest/index.html#support-desc>`__.
|
||||
@@ -250,9 +251,10 @@ Gondor
|
||||
~~~~~~
|
||||
|
||||
`Gondor <https://gondor.io/>`_ is a PaaS specialized for deploying Django
|
||||
and Pinax applications. Gondor recommends Django version 1.6 and supports any WSGI application on
|
||||
Python version 2.7. Gondor can automatically configure your Django site if you
|
||||
use :file:`local_settings.py` for site-specific configuration information.
|
||||
and Pinax applications. Gondor recommends Django version 1.6 and supports any
|
||||
WSGI application on Python version 2.7. Gondor can automatically configure your
|
||||
Django site if you use :file:`local_settings.py` for site-specific configuration
|
||||
information.
|
||||
|
||||
Gondor has a guide on deploying `Django projects <https://gondor.io/support/django/setup/>`_.
|
||||
|
||||
@@ -260,23 +262,20 @@ Gondor has a guide on deploying `Django projects <https://gondor.io/support/djan
|
||||
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
|
||||
advises us to use templates. A template engine manages 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.
|
||||
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 advises us to use templates. A
|
||||
template engine manages 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
|
||||
sometimes written by designers or front-end developers,
|
||||
it can be difficult to handle increasing complexity.
|
||||
sometimes written by designers or front-end developers, it can be difficult to
|
||||
handle increasing complexity.
|
||||
|
||||
Some general good practices apply to the part of the
|
||||
application passing dynamic content to the template engine,
|
||||
and to the templates themselves.
|
||||
Some general good practices 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
|
||||
|
||||
+20
-15
@@ -5,33 +5,36 @@ Packaging your code is important.
|
||||
|
||||
You'll need to package your code first before sharing it with other developers.
|
||||
|
||||
The `Python Packaging Guide <https://python-packaging-user-guide.readthedocs.org/en/latest/>`_ provides an extensive guide on creating and maintaining Python packages.
|
||||
The `Python Packaging Guide <https://python-packaging-user-guide.readthedocs.org/en/latest/>`_
|
||||
provides an extensive guide on creating and maintaining Python packages.
|
||||
|
||||
For Python Developers
|
||||
:::::::::::::::::::::
|
||||
|
||||
If you're writing an open source Python module, `PyPI <http://pypi.python.org>`_,
|
||||
more properly known as *The Cheeseshop*, is the place to host it.
|
||||
If you're writing an open source Python module, `PyPI <http://pypi.python.org>`_
|
||||
, more properly known as *The Cheeseshop*, is the place to host it.
|
||||
|
||||
|
||||
|
||||
Pip vs. easy_install
|
||||
--------------------
|
||||
|
||||
Use `pip <http://pypi.python.org/pypi/pip>`_. More details `here <http://stackoverflow.com/questions/3220404/why-use-pip-over-easy-install>`_
|
||||
Use `pip <http://pypi.python.org/pypi/pip>`_. More details
|
||||
`here <http://stackoverflow.com/questions/3220404/why-use-pip-over-easy-install>`_
|
||||
|
||||
|
||||
Personal PyPI
|
||||
-------------
|
||||
|
||||
If you want to install packages from a source other than PyPI, (say, if
|
||||
your packages are *proprietary*), you can do it by hosting a simple http server,
|
||||
running from the directory which holds those packages which need to be installed.
|
||||
your packages are *proprietary*), you can do it by hosting a simple http
|
||||
server, running from the directory which holds those packages which need to be
|
||||
installed.
|
||||
|
||||
**Showing an example is always beneficial**
|
||||
|
||||
For example, if you want to install a package called :file:`MyPackage.tar.gz`, and
|
||||
assuming this is your directory structure:
|
||||
For example, if you want to install a package called :file:`MyPackage.tar.gz`,
|
||||
and assuming this is your directory structure:
|
||||
|
||||
|
||||
- archive
|
||||
@@ -55,8 +58,8 @@ package installer. Using Pip, you would do it like:
|
||||
|
||||
Having a folder with the same name as the package name is **crucial** here.
|
||||
I got fooled by that, one time. But if you feel that creating a folder called
|
||||
:file:`MyPackage` and keeping :file:`MyPackage.tar.gz` inside that, is *redundant*,
|
||||
you can still install MyPackage using:
|
||||
:file:`MyPackage` and keeping :file:`MyPackage.tar.gz` inside that, is
|
||||
*redundant*, you can still install MyPackage using:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -65,16 +68,18 @@ you can still install MyPackage using:
|
||||
pypiserver
|
||||
++++++++++
|
||||
|
||||
`Pypiserver <https://pypi.python.org/pypi/pypiserver>`_ is a minimal PyPI compatible server.
|
||||
It can be used to serve a set of packages to easy_install or pip. It includes helpful
|
||||
features like an administrative command (:option:`-U`) which will update all its packages to their
|
||||
latest versions found on PyPI.
|
||||
`Pypiserver <https://pypi.python.org/pypi/pypiserver>`_ is a minimal PyPI
|
||||
compatible server. It can be used to serve a set of packages to easy_install
|
||||
or pip. It includes helpful features like an administrative command
|
||||
(:option:`-U`) which will update all its packages to their latest versions
|
||||
found on PyPI.
|
||||
|
||||
|
||||
S3-Hosted PyPi
|
||||
++++++++++++++
|
||||
|
||||
One simple option for a personal PyPi server is to use Amazon S3. A prerequisite for this is that you have an Amazon AWS account with an S3 bucket.
|
||||
One simple option for a personal PyPi server is to use Amazon S3. A
|
||||
prerequisite for this is that you have an Amazon AWS account with an S3 bucket.
|
||||
|
||||
1. **Install all your requirements from PyPi or another source**
|
||||
2. **Install pip2pi**
|
||||
|
||||
@@ -6,51 +6,53 @@ Further Configuration of Pip and Virtualenv
|
||||
Requiring an active virtual environment for ``pip``
|
||||
---------------------------------------------------
|
||||
|
||||
By now it should be clear that using virtual envirtonments is a great way to keep
|
||||
your development environment clean and keeping different projects' requirements
|
||||
separate.
|
||||
By now it should be clear that using virtual envirtonments is a great way to
|
||||
keep your development environment clean and keeping different projects'
|
||||
requirements separate.
|
||||
|
||||
When you start working on many different projects, it can be hard to remember to
|
||||
activate the related virtual environment when you come back to a specific project.
|
||||
As a result of this, it is very easy to install packages globally while thinking
|
||||
that you are actually installing the package for the virtual environment of the
|
||||
project. Over time this can result in a messy global package list.
|
||||
activate the related virtual environment when you come back to a specific
|
||||
project. As a result of this, it is very easy to install packages globally
|
||||
while thinking that you are actually installing the package for the virtual
|
||||
environment of the project. Over time this can result in a messy global package
|
||||
list.
|
||||
|
||||
In order to make sure that you install packages to your active virtual environment
|
||||
when you use ``pip install``, consider adding the following two lines to your
|
||||
:file:`~/.bashrc` file:
|
||||
In order to make sure that you install packages to your active virtual
|
||||
environment when you use ``pip install``, consider adding the following two
|
||||
lines to your :file:`~/.bashrc` file:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
export PIP_REQUIRE_VIRTUALENV=true
|
||||
|
||||
After saving this change and sourcing the :file:`~/.bashrc` file with ``source ~/.bashrc``,
|
||||
pip will no longer let you install packages if you are not in a virtual environment.
|
||||
If you try to use ``pip install`` outside of a virtual environment pip will gently
|
||||
remind you that an activated virtual environment is needed to install packages.
|
||||
After saving this change and sourcing the :file:`~/.bashrc` file with
|
||||
``source ~/.bashrc``, pip will no longer let you install packages if you are not
|
||||
in a virtual environment. If you try to use ``pip install`` outside of a
|
||||
virtual environment pip will gently remind you that an activated virtual
|
||||
environment is needed to install packages.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ pip install requests
|
||||
Could not find an activated virtualenv (required).
|
||||
|
||||
You can also do this configuration by editing your :file:`pip.conf` or :file:`pip.ini`
|
||||
file. :file:`pip.conf` is used by Unix and Mac OS X operating systems and it can be
|
||||
found at:
|
||||
You can also do this configuration by editing your :file:`pip.conf` or
|
||||
:file:`pip.ini` file. :file:`pip.conf` is used by Unix and Mac OS X operating
|
||||
systems and it can be found at:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$HOME/.pip/pip.conf
|
||||
|
||||
Similarly, the :file:`pip.ini` file is used by Windows operating systems and it can
|
||||
be found at:
|
||||
Similarly, the :file:`pip.ini` file is used by Windows operating systems and it
|
||||
can be found at:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
%HOME%\pip\pip.ini
|
||||
|
||||
If you don't have a :file:`pip.conf` or :file:`pip.ini` file at these locations, you can
|
||||
create a new file with the correct name for your operating system.
|
||||
If you don't have a :file:`pip.conf` or :file:`pip.ini` file at these locations,
|
||||
you can create a new file with the correct name for your operating system.
|
||||
|
||||
If you already have a configuration file, just add the following line under the
|
||||
``[global]`` settings to require an active virtual environment:
|
||||
@@ -68,9 +70,9 @@ add the following lines to this new file:
|
||||
require-virtualenv = true
|
||||
|
||||
|
||||
You will of course need to install some packages globally (usually ones that you
|
||||
use across different projects consistenly) and this can be accomplished by adding
|
||||
the following to your :file:`~/.bashrc` file:
|
||||
You will of course need to install some packages globally (usually ones that
|
||||
you use across different projects consistenly) and this can be accomplished by
|
||||
adding the following to your :file:`~/.bashrc` file:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -78,38 +80,38 @@ the following to your :file:`~/.bashrc` file:
|
||||
PIP_REQUIRE_VIRTUALENV="" pip "$@"
|
||||
}
|
||||
|
||||
After saving the changes and sourcing your :file:`~/.bashrc` file you can now install
|
||||
packages globally by running ``gpip install``. You can change the name of the
|
||||
function to anything you like, just keep in mind that you will have to use that
|
||||
name when trying to install packages globally with pip.
|
||||
After saving the changes and sourcing your :file:`~/.bashrc` file you can now
|
||||
install packages globally by running ``gpip install``. You can change the name
|
||||
of the function to anything you like, just keep in mind that you will have to
|
||||
use that name when trying to install packages globally with pip.
|
||||
|
||||
Caching packages for future use
|
||||
-------------------------------
|
||||
|
||||
Every developer has preferred libraries and when you are working on a lot of
|
||||
different projects, you are bound to have some overlap between the libraries that
|
||||
you use. For example, you may be using the ``requests`` library in a lot of different
|
||||
projects.
|
||||
different projects, you are bound to have some overlap between the libraries
|
||||
that you use. For example, you may be using the ``requests`` library in a lot
|
||||
of different projects.
|
||||
|
||||
It is surely unnecessary to re-download the same packages/libraries each time you
|
||||
start working on a new project (and in a new virtual environmen as a result).
|
||||
It is surely unnecessary to re-download the same packages/libraries each time
|
||||
you start working on a new project (and in a new virtual environmen as a result).
|
||||
Fortunately, you can configure pip in such a way that it tries to reuse already
|
||||
installed packages.
|
||||
|
||||
On UNIX systems, you can add the following line to your :file:`.bashrc` or :file:`.bash_profile`
|
||||
file.
|
||||
On UNIX systems, you can add the following line to your :file:`.bashrc` or
|
||||
:file:`.bash_profile` file.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
export PIP_DOWNLOAD_CACHE=$HOME/.pip/cache
|
||||
|
||||
You can set the path to anywhere you like (as long as you have write
|
||||
access). After adding this line, ``source`` your :file:`.bashrc` (or :file:`.bash_profile`)
|
||||
file and you will be all set.
|
||||
access). After adding this line, ``source`` your :file:`.bashrc`
|
||||
(or :file:`.bash_profile`) file and you will be all set.
|
||||
|
||||
Another way of doing the same configuration is via the :file:`pip.conf` or :file:`pip.ini`
|
||||
files, depending on your system. If you are on Windows, you can add the following
|
||||
line to your :file:`pip.ini` file under ``[global]`` settings:
|
||||
Another way of doing the same configuration is via the :file:`pip.conf` or
|
||||
:file:`pip.ini` files, depending on your system. If you are on Windows, you can
|
||||
add the following line to your :file:`pip.ini` file under ``[global]`` settings:
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
@@ -123,6 +125,6 @@ Similarly, on UNIX systems you should simply add the following line to your
|
||||
download-cache = $HOME/.pip/cache
|
||||
|
||||
Even though you can use any path you like to store your cache, it is recommended
|
||||
that you create a new folder *in* the folder where your :file:`pip.conf` or :file:`pip.ini`
|
||||
file lives. If you don't trust yourself with all of this path voodoo, just use
|
||||
the values provided here and you will be fine.
|
||||
that you create a new folder *in* the folder where your :file:`pip.conf` or
|
||||
:file:`pip.ini` file lives. If you don't trust yourself with all of this path
|
||||
voodoo, just use the values provided here and you will be fine.
|
||||
|
||||
@@ -2,10 +2,9 @@ Choosing a License
|
||||
==================
|
||||
|
||||
Your source publication *needs* a license. In the US, if no license is
|
||||
specified, users have no legal right to download, modify, or
|
||||
distribute. Furthermore, people can't contribute to your code unless
|
||||
you tell them what rules to play by. Choosing a license is complicated, so
|
||||
here are some pointers:
|
||||
specified, users have no legal right to download, modify, or distribute.
|
||||
Furthermore, people can't contribute to your code unless you tell them what
|
||||
rules to play by. Choosing a license is complicated, so here are some pointers:
|
||||
|
||||
Open source. There are plenty of `open source licenses
|
||||
<http://opensource.org/licenses/alphabetical>`_ available to choose
|
||||
|
||||
@@ -23,11 +23,10 @@ the goal is to display a help statement for a command line application.
|
||||
Other reasons why logging is better than ``print``:
|
||||
|
||||
- The `log record`_, which is created with every logging event, contains
|
||||
readily available diagnostic information such as the file name,
|
||||
full path, function, and line number of the logging event.
|
||||
- Events logged in included modules are automatically accessible via the
|
||||
root logger
|
||||
to your application's logging stream, unless you filter them out.
|
||||
readily available diagnostic information such as the file name, full path,
|
||||
function, and line number of the logging event.
|
||||
- Events logged in included modules are automatically accessible via the root
|
||||
logger to your application's logging stream, unless you filter them out.
|
||||
- Logging can be selectively silenced by using the method
|
||||
:meth:`logging.Logger.setLevel` or disabled by setting the attribute
|
||||
:attr:`logging.Logger.disabled` to ``True``.
|
||||
@@ -83,15 +82,14 @@ application environment.
|
||||
There are at least three ways to configure a logger:
|
||||
|
||||
- Using an INI-formatted file:
|
||||
- **Pro**: possible to update configuration while running
|
||||
using the function :func:`logging.config.listen` to listen
|
||||
on a socket.
|
||||
- **Pro**: possible to update configuration while running using the
|
||||
function :func:`logging.config.listen` to listen on a socket.
|
||||
- **Con**: less control (*e.g.* custom subclassed filters or loggers)
|
||||
than possible when configuring a logger in code.
|
||||
- Using a dictionary or a JSON-formatted file:
|
||||
- **Pro**: in addition to updating while running, it is possible to
|
||||
load from a file using the :mod:`json` module, in the standard
|
||||
library since Python 2.6.
|
||||
- **Pro**: in addition to updating while running, it is possible to load
|
||||
from a file using the :mod:`json` module, in the standard library since
|
||||
Python 2.6.
|
||||
- **Con**: less control than when configuring a logger in code.
|
||||
- Using code:
|
||||
- **Pro**: complete control over the configuration.
|
||||
|
||||
+74
-71
@@ -34,8 +34,8 @@ to do it poorly. Some signs of a poorly structured project
|
||||
include:
|
||||
|
||||
- Multiple and messy circular dependencies: if your classes
|
||||
Table and Chair in :file:`furn.py` need to import Carpenter from :file:`workers.py`
|
||||
to answer a question such as ``table.isdoneby()``,
|
||||
Table and Chair in :file:`furn.py` need to import Carpenter from
|
||||
:file:`workers.py` to answer a question such as ``table.isdoneby()``,
|
||||
and if conversely the class Carpenter needs to import Table and Chair,
|
||||
to answer the question ``carpenter.whatdo()``, then you
|
||||
have a circular dependency. In this case you will have to resort to
|
||||
@@ -85,17 +85,17 @@ in one file, and all low-level operations in another file. In this case,
|
||||
the interface file needs to import the low-level file. This is done with the
|
||||
``import`` and ``from ... import`` statements.
|
||||
|
||||
As soon as you use `import` statements you use modules. These can be either built-in
|
||||
modules such as `os` and `sys`, third-party modules you have installed in your
|
||||
environment, or your project's internal modules.
|
||||
As soon as you use `import` statements you use modules. These can be either
|
||||
built-in modules such as `os` and `sys`, third-party modules you have installed
|
||||
in your environment, or your project's internal modules.
|
||||
|
||||
To keep in line with the style guide, keep module names short, lowercase, and
|
||||
be sure to avoid using special symbols like the dot (.) or question mark (?).
|
||||
So a file name like :file:`my.spam.py` is one you should avoid! Naming this way
|
||||
will interfere with the way Python looks for modules.
|
||||
|
||||
In the case of `my.spam.py` Python expects to find a :file:`spam.py` file in a folder named :file:`my`
|
||||
which is not the case. There is an
|
||||
In the case of `my.spam.py` Python expects to find a :file:`spam.py` file in a
|
||||
folder named :file:`my` which is not the case. There is an
|
||||
`example <http://docs.python.org/tutorial/modules.html#packages>`_ of how the
|
||||
dot notation should be used in the Python docs.
|
||||
|
||||
@@ -106,18 +106,18 @@ Aside from some naming restrictions, nothing special is required for a Python
|
||||
file to be a module, but you need to understand the import mechanism in order
|
||||
to use this concept properly and avoid some issues.
|
||||
|
||||
Concretely, the ``import modu`` statement will look for the proper file, which is
|
||||
:file:`modu.py` in the same directory as the caller if it exists. If it is not
|
||||
found, the Python interpreter will search for :file:`modu.py` in the "path"
|
||||
Concretely, the ``import modu`` statement will look for the proper file, which
|
||||
is :file:`modu.py` in the same directory as the caller if it exists. If it is
|
||||
not found, the Python interpreter will search for :file:`modu.py` in the "path"
|
||||
recursively and raise an ImportError exception if it is not found.
|
||||
|
||||
Once :file:`modu.py` is found, the Python interpreter will execute the module in an
|
||||
isolated scope. Any top-level statement in :file:`modu.py` will be executed,
|
||||
Once :file:`modu.py` is found, the Python interpreter will execute the module in
|
||||
an isolated scope. Any top-level statement in :file:`modu.py` will be executed,
|
||||
including other imports if any. Function and class definitions are stored in
|
||||
the module's dictionary.
|
||||
|
||||
Then, the module's variables, functions, and classes will be available to the caller
|
||||
through the module's namespace, a central concept in programming that is
|
||||
Then, the module's variables, functions, and classes will be available to the
|
||||
caller through the module's namespace, a central concept in programming that is
|
||||
particularly helpful and powerful in Python.
|
||||
|
||||
In many languages, an ``include file`` directive is used by the preprocessor to
|
||||
@@ -127,14 +127,15 @@ means that you generally don't have to worry that the included code could have
|
||||
unwanted effects, e.g. override an existing function with the same name.
|
||||
|
||||
It is possible to simulate the more standard behavior by using a special syntax
|
||||
of the import statement: ``from modu import *``. This is generally considered bad
|
||||
practice. **Using** ``import *`` **makes code harder to read and makes dependencies less
|
||||
compartmentalized**.
|
||||
of the import statement: ``from modu import *``. This is generally considered
|
||||
bad practice. **Using** ``import *`` **makes code harder to read and makes
|
||||
dependencies less compartmentalized**.
|
||||
|
||||
Using ``from modu import func`` is a way to pinpoint the function you want to
|
||||
import and put it in the global namespace. While much less harmful than ``import
|
||||
*`` because it shows explicitly what is imported in the global namespace, its
|
||||
only advantage over a simpler ``import modu`` is that it will save a little typing.
|
||||
only advantage over a simpler ``import modu`` is that it will save a little
|
||||
typing.
|
||||
|
||||
**Very bad**
|
||||
|
||||
@@ -176,29 +177,32 @@ Packages
|
||||
Python provides a very straightforward packaging system, which is simply an
|
||||
extension of the module mechanism to a directory.
|
||||
|
||||
Any directory with an :file:`__init__.py` file is considered a Python package. The
|
||||
different modules in the package are imported in a similar manner as plain
|
||||
modules, but with a special behavior for the :file:`__init__.py` file, which is used to
|
||||
gather all package-wide definitions.
|
||||
Any directory with an :file:`__init__.py` file is considered a Python package.
|
||||
The different modules in the package are imported in a similar manner as plain
|
||||
modules, but with a special behavior for the :file:`__init__.py` file, which is
|
||||
used to gather all package-wide definitions.
|
||||
|
||||
A file :file:`modu.py` in the directory :file:`pack/` is imported with the statement ``import
|
||||
pack.modu``. This statement will look for an :file:`__init__.py` file in :file:`pack`, execute
|
||||
all of its top-level statements. Then it will look for a file named :file:`pack/modu.py` and
|
||||
A file :file:`modu.py` in the directory :file:`pack/` is imported with the
|
||||
statement ``import pack.modu``. This statement will look for an
|
||||
:file:`__init__.py` file in :file:`pack`, execute all of its top-level
|
||||
statements. Then it will look for a file named :file:`pack/modu.py` and
|
||||
execute all of its top-level statements. After these operations, any variable,
|
||||
function, or class defined in :file:`modu.py` is available in the pack.modu namespace.
|
||||
function, or class defined in :file:`modu.py` is available in the pack.modu
|
||||
namespace.
|
||||
|
||||
A commonly seen issue is to add too much code to :file:`__init__.py`
|
||||
files. When the project complexity grows, there may be sub-packages and
|
||||
sub-sub-packages in a deep directory structure. In this case, importing a single item
|
||||
from a sub-sub-package will require executing all :file:`__init__.py` files met while
|
||||
traversing the tree.
|
||||
sub-sub-packages in a deep directory structure. In this case, importing a
|
||||
single item from a sub-sub-package will require executing all
|
||||
:file:`__init__.py` files met while traversing the tree.
|
||||
|
||||
Leaving an :file:`__init__.py` file empty is considered normal and even a good practice,
|
||||
if the package's modules and sub-packages do not need to share any code.
|
||||
Leaving an :file:`__init__.py` file empty is considered normal and even a good
|
||||
practice, if the package's modules and sub-packages do not need to share any
|
||||
code.
|
||||
|
||||
Lastly, a convenient syntax is available for importing deeply nested packages:
|
||||
``import very.deep.module as mod``. This allows you to use `mod` in place of the verbose
|
||||
repetition of ``very.deep.module``.
|
||||
``import very.deep.module as mod``. This allows you to use `mod` in place of the
|
||||
verbose repetition of ``very.deep.module``.
|
||||
|
||||
Object-oriented programming
|
||||
---------------------------
|
||||
@@ -232,27 +236,28 @@ 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, multiple instances of Python
|
||||
processes are spawned to respond to external requests that can
|
||||
happen at the same time. In this case, holding some state into instantiated
|
||||
objects, which means keeping some static information about the world, is prone
|
||||
to concurrency problems or race-conditions. Sometimes, between the initialization of
|
||||
the state of an object (usually done with the ``__init__()`` method) and the actual use
|
||||
processes are spawned to respond to external requests that can happen at the
|
||||
same time. In this case, holding some state into instantiated objects, which
|
||||
means keeping some static information about the world, is prone to concurrency
|
||||
problems or race-conditions. Sometimes, 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 methods, 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 time, it may happen that the deletion actually occurs after
|
||||
the first process loaded the item, and then we have to mark as read a deleted
|
||||
object.
|
||||
of this item at the same time, it may happen that the deletion actually occurs
|
||||
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 suggest using functions and procedures
|
||||
with as few implicit contexts and side-effects as possible. A function's
|
||||
implicit context is made up of any of the global variables or items in the persistence layer
|
||||
that are accessed from within the function. Side-effects are the changes that a function makes
|
||||
to its implicit context. If a function saves or deletes data in a global variable or
|
||||
in the persistence layer, it is said to have a side-effect.
|
||||
implicit context is made up of any of the global variables or items in the
|
||||
persistence layer that are accessed from within the function. Side-effects are
|
||||
the changes that a function makes to its implicit context. If a function saves
|
||||
or deletes data in a global variable or in the persistence layer, it is said to
|
||||
have a side-effect.
|
||||
|
||||
Carefully isolating functions with context and side-effects from functions with
|
||||
logic (called pure functions) allow the following benefits:
|
||||
@@ -314,19 +319,18 @@ of the function logic.
|
||||
Dynamic typing
|
||||
--------------
|
||||
|
||||
Python is dynamically typed, which means that variables
|
||||
do not have a fixed type. In fact, in Python, variables are very
|
||||
different from what they are in many other languages, specifically
|
||||
statically-typed languages. Variables are not a segment of the computer's
|
||||
memory where some value is written, they are 'tags' or 'names' pointing
|
||||
to objects. It is therefore possible for the variable 'a' to be set to
|
||||
the value 1, then to the value 'a string', then to a function.
|
||||
Python is dynamically typed, which means that variables do not have a fixed
|
||||
type. In fact, in Python, variables are very different from what they are in
|
||||
many other languages, specifically statically-typed languages. Variables are not
|
||||
a segment of the computer's memory where some value is written, they are 'tags'
|
||||
or 'names' pointing to objects. It is therefore possible for the variable 'a' to
|
||||
be set to the value 1, then to the value 'a string', then to a function.
|
||||
|
||||
The dynamic typing of Python is often considered to be a weakness, and indeed
|
||||
it can lead to complexities and hard-to-debug code. Something
|
||||
named 'a' can be set to many different things, and the developer or the
|
||||
maintainer needs to track this name in the code to make sure it has not
|
||||
been set to a completely unrelated object.
|
||||
it can lead to complexities and hard-to-debug code. Something named 'a' can be
|
||||
set to many different things, and the developer or the maintainer needs to track
|
||||
this name in the code to make sure it has not been set to a completely unrelated
|
||||
object.
|
||||
|
||||
Some guidelines help to avoid this issue:
|
||||
|
||||
@@ -370,26 +374,25 @@ grows and each assignment is separated by other lines of code, including
|
||||
'if' branches and loops, it becomes harder to ascertain what a given
|
||||
variable's type is.
|
||||
|
||||
Some coding practices, like functional programming, recommend never reassigning a variable.
|
||||
In Java this is done with the `final` keyword. Python does not have a `final` keyword
|
||||
and it would be against its philosophy anyway. However, it may be a good
|
||||
discipline to avoid assigning to a variable more than once, and it helps
|
||||
in grasping the concept of mutable and immutable types.
|
||||
Some coding practices, like functional programming, recommend never reassigning
|
||||
a variable. In Java this is done with the `final` keyword. Python does not have
|
||||
a `final` keyword and it would be against its philosophy anyway. However, it may
|
||||
be a good discipline to avoid assigning to a variable more than once, and it
|
||||
helps in grasping the concept of mutable and immutable types.
|
||||
|
||||
Mutable and immutable types
|
||||
---------------------------
|
||||
|
||||
Python has two kinds of built-in or user-defined types.
|
||||
|
||||
Mutable types are those that allow in-place modification
|
||||
of the content. Typical mutables are lists and dictionaries:
|
||||
All lists have mutating methods, like :py:meth:`list.append` or :py:meth:`list.pop`, and
|
||||
can be modified in place. The same goes for dictionaries.
|
||||
Mutable types are those that allow in-place modification of the content. Typical
|
||||
mutables are lists and dictionaries: All lists have mutating methods, like
|
||||
:py:meth:`list.append` or :py:meth:`list.pop`, and can be modified in place.
|
||||
The same goes for dictionaries.
|
||||
|
||||
Immutable types provide no method for changing their content.
|
||||
For instance, the variable x set to the integer 6 has no "increment" method. If you
|
||||
want to compute x + 1, you have to create another integer and give it
|
||||
a name.
|
||||
Immutable types provide no method for changing their content. For instance, the
|
||||
variable x set to the integer 6 has no "increment" method. If you want to
|
||||
compute x + 1, you have to create another integer and give it a name.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -451,8 +454,8 @@ with calls to ``append()``.
|
||||
One final thing to mention about strings is that using ``join()`` is not always
|
||||
best. In the instances where you are creating a new string from a pre-determined
|
||||
number of strings, using the addition operator is actually faster, but in cases
|
||||
like above or in cases where you are adding to an existing string, using ``join()``
|
||||
should be your preferred method.
|
||||
like above or in cases where you are adding to an existing string, using
|
||||
``join()`` should be your preferred method.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
|
||||
+82
-72
@@ -11,8 +11,8 @@ 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.
|
||||
|
||||
Moreover, when a veteran Python developer (a Pythonista) points to portions of code
|
||||
and says they are not "Pythonic", it usually means that these lines
|
||||
Moreover, when a veteran Python developer (a Pythonista) points to portions of
|
||||
code and says they are not "Pythonic", it usually means that these lines
|
||||
of code do not follow the common guidelines and fail to express the intent in
|
||||
what is considered the best (hear: most readable) way.
|
||||
|
||||
@@ -86,40 +86,42 @@ Function arguments
|
||||
|
||||
Arguments can be passed to functions in four different ways.
|
||||
|
||||
1. **Positional arguments** are mandatory and have no default values. They are the
|
||||
simplest form of arguments and they can be used for the few function arguments
|
||||
that are fully part of the function's meaning and their order is natural. For
|
||||
instance, in ``send(message, recipient)`` or ``point(x, y)`` the user of the
|
||||
function has no difficulty remembering that those two functions require two
|
||||
arguments, and in which order.
|
||||
1. **Positional arguments** are mandatory and have no default values. They are
|
||||
the simplest form of arguments and they can be used for the few function
|
||||
arguments that are fully part of the function's meaning and their order is
|
||||
natural. For instance, in ``send(message, recipient)`` or ``point(x, y)``
|
||||
the user of the function has no difficulty remembering that those two
|
||||
functions require two arguments, and in which order.
|
||||
|
||||
In those two cases, it is possible to use argument names when calling the functions
|
||||
and, doing so, it is possible to switch the order of arguments, calling for instance
|
||||
``send(recipient='World', message='Hello')`` and ``point(y=2, x=1)`` but this
|
||||
reduces readability and is unnecessarily verbose, compared to the more straightforward
|
||||
calls to ``send('Hello', 'World')`` and ``point(1, 2)``.
|
||||
In those two cases, it is possible to use argument names when calling the
|
||||
functions and, doing so, it is possible to switch the order of arguments,
|
||||
calling for instance ``send(recipient='World', message='Hello')`` and
|
||||
``point(y=2, x=1)`` but this reduces readability and is unnecessarily verbose,
|
||||
compared to the more straightforward calls to ``send('Hello', 'World')`` and
|
||||
``point(1, 2)``.
|
||||
|
||||
2. **Keyword arguments** are not mandatory and have default values. They are often
|
||||
used for optional parameters sent to the function. When a function has more than
|
||||
two or three positional parameters, its signature is more difficult to remember
|
||||
and using keyword arguments with default values is helpful. For instance, a more
|
||||
complete ``send`` function could be defined as ``send(message, to, cc=None, bcc=None)``.
|
||||
Here ``cc`` and ``bcc`` are optional, and evaluate to ``None`` when they are not
|
||||
passed another value.
|
||||
2. **Keyword arguments** are not mandatory and have default values. They are
|
||||
often used for optional parameters sent to the function. When a function has
|
||||
more than two or three positional parameters, its signature is more difficult
|
||||
to remember and using keyword arguments with default values is helpful. For
|
||||
instance, a more complete ``send`` function could be defined as
|
||||
``send(message, to, cc=None, bcc=None)``. Here ``cc`` and ``bcc`` are
|
||||
optional, and evaluate to ``None`` when they are not passed another value.
|
||||
|
||||
Calling a function with keyword arguments can be done in multiple ways in Python,
|
||||
for example it is possible to follow the order of arguments in the definition without
|
||||
explicitly naming the arguments, like in ``send('Hello', 'World', 'Cthulhu', 'God')``,
|
||||
sending a blind carbon copy to God. It would also be possible to name arguments in
|
||||
another order, like in ``send('Hello again', 'World', bcc='God', cc='Cthulhu')``.
|
||||
Those two possibilities are better avoided without any strong reason to not
|
||||
follow the syntax that is the closest to the function definition: ``send('Hello',
|
||||
'World', cc='Cthulhu', bcc='God')``.
|
||||
Calling a function with keyword arguments can be done in multiple ways in
|
||||
Python, for example it is possible to follow the order of arguments in the
|
||||
definition without explicitly naming the arguments, like in
|
||||
``send('Hello', 'World', 'Cthulhu', 'God')``, sending a blind carbon copy to
|
||||
God. It would also be possible to name arguments in another order, like in
|
||||
``send('Hello again', 'World', bcc='God', cc='Cthulhu')``. Those two
|
||||
possibilities are better avoided without any strong reason to not follow the
|
||||
syntax that is the closest to the function definition:
|
||||
``send('Hello', 'World', cc='Cthulhu', bcc='God')``.
|
||||
|
||||
As a side note, following `YAGNI <http://en.wikipedia.org/wiki/You_ain't_gonna_need_it>`_
|
||||
principle, it is often harder to remove an optional argument (and its logic inside the
|
||||
function) that was added "just in case" and is seemingly never used, than to add a
|
||||
new optional argument and its logic when needed.
|
||||
principle, it is often harder to remove an optional argument (and its logic
|
||||
inside the function) that was added "just in case" and is seemingly never used,
|
||||
than to add a new optional argument and its logic when needed.
|
||||
|
||||
3. The **arbitrary argument list** is the third way to pass arguments to a
|
||||
function. If the function intention is better expressed by a signature with an
|
||||
@@ -139,11 +141,12 @@ it explicitly: ``send(message, recipients)`` and call it with ``send('Hello',
|
||||
the recipient list as a list beforehand, and it opens the possibility to pass
|
||||
any sequence, including iterators, that cannot be unpacked as other sequences.
|
||||
|
||||
4. The **arbitrary keyword argument dictionary** is the last way to pass arguments
|
||||
to functions. If the function requires an undetermined series of named
|
||||
arguments, it is possible to use the ``**kwargs`` construct. In the function
|
||||
body, ``kwargs`` will be a dictionary of all the passed named arguments that
|
||||
have not been caught by other keyword arguments in the function signature.
|
||||
4. The **arbitrary keyword argument dictionary** is the last way to pass
|
||||
arguments to functions. If the function requires an undetermined series of
|
||||
named arguments, it is possible to use the ``**kwargs`` construct. In the
|
||||
function body, ``kwargs`` will be a dictionary of all the passed named
|
||||
arguments that have not been caught by other keyword arguments in the
|
||||
function signature.
|
||||
|
||||
The same caution as in the case of *arbitrary argument list* is necessary, for
|
||||
similar reasons: these powerful techniques are to be used when there is a
|
||||
@@ -158,8 +161,8 @@ Python functions that are:
|
||||
|
||||
* easy to read (the name and arguments need no explanations)
|
||||
|
||||
* easy to change (adding a new keyword argument does not break other parts of the
|
||||
code)
|
||||
* easy to change (adding a new keyword argument does not break other parts of
|
||||
the code)
|
||||
|
||||
Avoid the magical wand
|
||||
~~~~~~~~~~~~~~~~~~~~~~
|
||||
@@ -198,8 +201,8 @@ give a lot of mechanisms to prevent any misuse, is expressed by the saying: "We
|
||||
are all consenting adults".
|
||||
|
||||
This doesn't mean that, for example, no properties are considered private, and
|
||||
that no proper encapsulation is possible in Python. Rather, instead of relying on
|
||||
concrete walls erected by the developers between their code and other's, the
|
||||
that no proper encapsulation is possible in Python. Rather, 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 conventions indicating that these
|
||||
elements should not be accessed directly.
|
||||
|
||||
@@ -217,27 +220,29 @@ but making a public property private might be a much harder operation.
|
||||
Returning values
|
||||
~~~~~~~~~~~~~~~~
|
||||
|
||||
When a function grows in complexity it is not uncommon to use multiple return statements
|
||||
inside the function's body. However, in order to keep a clear intent and a sustainable
|
||||
readability level, it is preferable to avoid returning meaningful values from many
|
||||
output points in the body.
|
||||
When a function grows in complexity it is not uncommon to use multiple return
|
||||
statements inside the function's body. However, in order to keep a clear intent
|
||||
and a sustainable readability level, it is preferable to avoid returning
|
||||
meaningful values from many output points in the body.
|
||||
|
||||
There are two main cases for returning values in a function: the result of the function
|
||||
return when it has been processed normally, and the error cases that indicate a wrong
|
||||
input parameter or any other reason for the function to not be able to complete its
|
||||
computation or task.
|
||||
There are two main cases for returning values in a function: the result of the
|
||||
function return when it has been processed normally, and the error cases that
|
||||
indicate a wrong input parameter or any other reason for the function to not be
|
||||
able to complete its computation or task.
|
||||
|
||||
If you do not wish to raise exceptions for the second case, then returning a value, such
|
||||
as None or False, indicating that the function could not perform correctly might be needed. In this
|
||||
case, it is better to return as early as the incorrect context has been detected. It will
|
||||
help to flatten the structure of the function: all the code after the return-because-of-error
|
||||
statement can assume the condition is met to further compute the function's main result.
|
||||
If you do not wish to raise exceptions for the second case, then returning a
|
||||
value, such as None or False, indicating that the function could not perform
|
||||
correctly might be needed. In this case, it is better to return as early as the
|
||||
incorrect context has been detected. It will help to flatten the structure of
|
||||
the function: all the code after the return-because-of-error statement can
|
||||
assume the condition is met to further compute the function's main result.
|
||||
Having multiple such return statements is often necessary.
|
||||
|
||||
However, when a function has multiple main exit points for its normal course, it becomes
|
||||
difficult to debug the returned result, so it may be preferable to keep a single exit
|
||||
point. This will also help factoring out some code paths, and the multiple exit points
|
||||
are a probable indication that such a refactoring is needed.
|
||||
However, when a function has multiple main exit points for its normal course,
|
||||
it becomes difficult to debug the returned result, so it may be preferable to
|
||||
keep a single exit point. This will also help factoring out some code paths,
|
||||
and the multiple exit points are a probable indication that such a refactoring
|
||||
is needed.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
@@ -256,14 +261,15 @@ are a probable indication that such a refactoring is needed.
|
||||
Idioms
|
||||
------
|
||||
|
||||
A programming idiom, put simply, is a *way* to write code. The notion of programming idioms
|
||||
is discussed amply at `c2 <http://c2.com/cgi/wiki?ProgrammingIdiom>`_ and at `Stack Overflow <http://stackoverflow.com/questions/302459/what-is-a-programming-idiom>`_.
|
||||
A programming idiom, put simply, is a *way* to write code. The notion of
|
||||
programming idioms is discussed amply at `c2 <http://c2.com/cgi/wiki?ProgrammingIdiom>`_
|
||||
and at `Stack Overflow <http://stackoverflow.com/questions/302459/what-is-a-programming-idiom>`_.
|
||||
|
||||
Idiomatic Python code is often referred to as being *Pythonic*.
|
||||
|
||||
Although there usually is one --- and preferably only one --- obvious way to do it;
|
||||
*the* way to write idiomatic Python code can be non-obvious to Python beginners. So,
|
||||
good idioms must be consciously acquired.
|
||||
Although there usually is one --- and preferably only one --- obvious way to do
|
||||
it; *the* way to write idiomatic Python code can be non-obvious to Python
|
||||
beginners. So, good idioms must be consciously acquired.
|
||||
|
||||
Some common Python idioms follow:
|
||||
|
||||
@@ -346,16 +352,19 @@ Instead, use a list comprehension:
|
||||
four_lists = [[] for __ in xrange(4)]
|
||||
|
||||
|
||||
A common idiom for creating strings is to use :py:meth:`str.join` on an empty string.
|
||||
A common idiom for creating strings is to use :py:meth:`str.join` on an empty
|
||||
string.
|
||||
|
||||
.. code-block:: python
|
||||
|
||||
letters = ['s', 'p', 'a', 'm']
|
||||
word = ''.join(letters)
|
||||
|
||||
This will set the value of the variable *word* to 'spam'. This idiom can be applied to lists and tuples.
|
||||
This will set the value of the variable *word* to 'spam'. This idiom can be
|
||||
applied to lists and tuples.
|
||||
|
||||
Sometimes we need to search through a collection of things. Let's look at two options: lists and dictionaries.
|
||||
Sometimes we need to search through a collection of things. Let's look at two
|
||||
options: lists and dictionaries.
|
||||
|
||||
Take the following code for example:
|
||||
|
||||
@@ -374,8 +383,9 @@ Even though both functions look identical, because *lookup_dict* is utilizing
|
||||
the fact that dictionaries in Python are hashtables, the lookup performance
|
||||
between the two is very different. Python will have to go through each item
|
||||
in the list to find a matching case, which is time consuming. By analysing
|
||||
the hash of the dictionary, finding keys in the dictionary can be done very quickly.
|
||||
For more information see this `StackOverflow <http://stackoverflow.com/questions/513882/python-list-vs-dict-for-look-up-table>`_
|
||||
the hash of the dictionary, finding keys in the dictionary can be done very
|
||||
quickly. For more information see this
|
||||
`StackOverflow <http://stackoverflow.com/questions/513882/python-list-vs-dict-for-look-up-table>`_
|
||||
page.
|
||||
|
||||
Zen of Python
|
||||
@@ -604,11 +614,11 @@ Line Continuations
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
When a logical line of code is longer than the accepted limit, you need to
|
||||
split it over multiple physical lines. The Python interpreter will join consecutive
|
||||
lines if the last character of the line is a backslash. This is helpful
|
||||
in some cases, but should usually be avoided because of its fragility: a white space
|
||||
added to the end of the line, after the backslash, will break the code and may
|
||||
have unexpected results.
|
||||
split it over multiple physical lines. The Python interpreter will join
|
||||
consecutive lines if the last character of the line is a backslash. This is
|
||||
helpful in some cases, but should usually be avoided because of its fragility:
|
||||
a white space added to the end of the line, after the backslash, will break the
|
||||
code and may have unexpected results.
|
||||
|
||||
A better solution is to use parentheses around your elements. Left with an
|
||||
unclosed parenthesis on an end-of-line the Python interpreter will join the
|
||||
|
||||
@@ -20,11 +20,11 @@ Some general rules of testing:
|
||||
|
||||
- Try hard to make tests that run fast. If one single test needs more than a
|
||||
few milliseconds to run, development will be slowed down or the tests will
|
||||
not be run as often as is desirable. In some cases, tests can't be fast because
|
||||
they need a complex data structure to work on, and this data structure must
|
||||
be loaded every time the test runs. Keep these heavier tests in a separate
|
||||
test suite that is run by some scheduled task, and run all other tests as
|
||||
often as needed.
|
||||
not be run as often as is desirable. In some cases, tests can't be fast
|
||||
because they need a complex data structure to work on, and this data structure
|
||||
must be loaded every time the test runs. Keep these heavier tests in a
|
||||
separate test suite that is run by some scheduled task, and run all other
|
||||
tests as often as needed.
|
||||
|
||||
- Learn your tools and learn how to run a single test or a test case. Then,
|
||||
when developing a function inside a module, run this function's tests very
|
||||
|
||||
Reference in New Issue
Block a user