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
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:
To delete a virtual environment, just delete its folder.
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:
To delete it:
$ rmvirtualenv test
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
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
- 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.
self.assert...instead of Python's
assertto 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()
$ python -m unittest <filename>
- Good practices: use a main test case class, use setup and teardown methods.
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)
$ python manage.py test
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:
You can also drop this to pdb:
$ py.test --pdb
The test is run on everything in docstrings:
''' >>> 1 == 1 False ''' if __name__ == '__main__': import doctest doctest.testmod()
Nose finds all the files that start with test and run for you. More information here.
# run tests over the directory $ nosetest
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
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()
$ 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:
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.
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:
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.