8-aeka
Last Updated: February 25, 2016
·
1.486K
· bt3gl
1396323302436

Python Good Practices

Virtual Environments

A virtual environment is a private copy of the Python interpreter, onto which you can install packages privately, without affecting the global Python interpreter installed in your system.

The more projects you have, the more likely it is that you will be working with different versions of Python itself, or at least different versions of Python libraries. For this reason, we use virtual environments.

For instance, you can always check your environment configuration with:

$ pip freeze

Virtualenv

Install virtualev:
sudo pip install virtualenv

Create a virtual environment:

$ virtualenv venv

To begin using the virtual environment, it needs to be activated:

$ source venv/bin/activate

If you are done working in the virtual environment for the moment, you can deactivate it:

$ deactivate

To delete a virtual environment, just delete its folder.


Virtualenvwrapper

Virtualenvwrapper provides a set of commands and also places all your virtual environments in one place.

To install it, make sure virtualenv is already installed, then:

$ pip install virtualenvwrapper

Add this to your .bashrc file:

export WORKON_HOME=$HOME/.virtualenvs
export PROJECT_HOME=$HOME/Devel
source /usr/local/bin/virtualenvwrapper.sh

To create a virtual environment:

$ mkvirtualenv test

To check if it is working:

$ which python
$ pip freeze

To work on a virtual environment:

$ workon test

To deactivate the environment:

$ deactivate

To delete it:

$ rmvirtualenv test

Why?

Because now we can have a file with all the requirements of your project, and install it anywhere you setup your work environment with:

pip install -r requirements.txt

Debugging

pdb, the Python debugger:

An introduction to pdb can be found here.

For example, you can use the option -i to run a script, and then it goes to an interactive session with the Python interpreter:

$ python -i 

Another way of debugging is by setting traces inside your code. For instance, you can write the following snippet inside the function that you want to inspect:

import pdb
pdb.set_trace() # where you want to start to debug

When running from the console, some useful commands are:

(Pdb) list      <- show next 10 lines
(Pdb) p self    <- point  
(Pdb) n         <- next line
(Pdb) help
(Pdb) exit

Unit Tests

Unittest

  • Standard testing package in Python standard library.
  • The files must start with test_.
  • Test isolation: Every test gets a new test object, failure does not stop tests, and test do not affect each other.
  • use self.assert... instead of Python's assert to show not only the failed value but also the actual value.
import unittest

class BasicsTestCase(unittest.TestCase):

    def test_find_name(self):
        self.assertTrue(1 == 1)
        self.assertFalse(1 == 2)

if __name__ == '__main__':
    unittest.main()

Run with:

$ python -m unittest <filename>
  • Good practices: use a main test case class, use setup and teardown methods.

Scripting

You can add a custom command to a script in your app, such as manage.py:

@manager.command
def test():
    """Run the unit tests."""
    import unittest
    tests = unittest.TestLoader().discover('tests')
    unittest.TextTestRunner(verbosity=2).run(tests)

To run:

$ python manage.py test

pytest

To use pytest, you just need to include a function that starts with test_ in a file that starts with test_. More information here.

You install with:

$ pip install pytest

For example, create a file with:

def func(x):
    return x + 1

def test_answer():
    assert func(3) == 5

And run with:

$ py.test

You can also drop this to pdb:

$ py.test --pdb

Doctest

The test is run on everything in docstrings:

'''
>>> 1 == 1
False
'''
if __name__ == '__main__':
    import doctest
    doctest.testmod()

nosetest

Nose finds all the files that start with test and run for you. More information here.

# run tests over the directory
$ nosetest

Coverage

Code coverage tools measure how much of the application is exercised by unit tests
and can provide a detailed report that indicates which parts of the application code are
not being tested. To install coverage in Python:

$ pip install coverage

To run from the command line:

$ coverage run file.py
$  coverage report -m

Finally, you can create a HTML coverage version:

$ coverage html

Scripting

We can integrate the coverage metrics to a manage.py file in our application. For example:

#!/usr/bin/env python
import os
COV = None
if os.environ.get('FLASK_COVERAGE'):
     import coverage
     COV = coverage.coverage(branch=True, include='app/*')
     COV.start()
@manager.command
def test(coverage=False):
    """Run the unit tests."""
    if coverage and not os.environ.get('FLASK_COVERAGE'):
       import sys
       os.environ['FLASK_COVERAGE'] = '1'
       os.execvp(sys.executable, [sys.executable] + sys.argv)
   if COV:
      COV.stop()
      COV.save()
      print('Coverage Summary:')
      COV.report()
      basedir = os.path.abspath(os.path.dirname(__file__))
      covdir = os.path.join(basedir, 'tmp/coverage')
      COV.html_report(directory=covdir)
      print('HTML version: file://%s/index.html' % covdir)
      COV.erase()

To run:

$ python manage.py test --coverage

Unicode and Style

All strings are Unicode in Python 3. However, in Python 2, there are lots of problems with UTF-8 and ASCII conversion. You can use codecs module:

import codecs

An example of code before:

with open("doc.txt", "r") as f:
     lines = [line.strip('\n') for line in f]
     print lines

Now, using codecs:

with codecs.open("doc.txt", encoding='utf-8') as f:
     lines = [line.strip('\n') for line in f]
     print lines

Finally, you should know that the convection used when you write a code in Python are deffined by PEP 8 (Python Enhancement Proposal 8).

To fix style issues, you can use pep8ify.

--

Interpreters

Now, let us talk about the interpreter: the command line environment to directly run code. The first one is the REPL (Read-Evaluate-Print Loop), which comes with the Python installation. You use it simply typing:

$ python

A second option is IPython, which allows you to make notebooks suitable for the web.

Finally, you can use bpython, which has a great GUI integrated with Python's documentation.


Further References

Say Thanks
Respond