Python Virtual Environments

De wikijoan
Salta a la navegació Salta a la cerca

Introducció

En el procés d'aprenentatge de TensorFlow m'he fet molt embolic amb les versions de les llibreries. És possible seguir un tutorial, i les llibreries que necessito són més antigues que les que tinc. O al revés. A més, puc treballar amb varis projectes alhora, que necessien la mateixa llibreria però diferents versions. És en aquest context que va bé treballar amb els Entorns Virtuals.

Teoria

Seguim:

>>> import sys
>>> sys.prefix
'/usr'
>>> 
>>> import site
>>> site.getsitepackages()
['/usr/local/lib/python3.6/dist-packages', '/usr/lib/python3/dist-packages', '/usr/lib/python3.6/dist-packages']

At its core, the main purpose of Python virtual environments is to create an isolated environment for Python projects. This means that each project can have its own dependencies, regardless of what dependencies every other project has.

In our little example above, we’d just need to create a separate virtual environment for both ProjectA and ProjectB, and we’d be good to go. Each environment, in turn, would be able to depend on whatever version of ProjectC they choose, independent of the other.

The great thing about this is that there are no limits to the number of environments you can have since they’re just directories containing a few scripts. Plus, they’re easily created using the virtualenv or pyenv command line tools.

If you are using Python 3, then you should already have the venv module from the standard library installed. (no cal instal·lar el mòdul virtualenv).

Start by making a new directory to work with:

$ mkdir python-virtual-environments && cd python-virtual-environments

Create a new virtual environment inside the directory:

# Python 2:
$ virtualenv env

# Python 3
$ python3 -m venv env -> aquesta és la meva opció

Note: By default, this will not include any of your existing site packages.

Però en Ubuntu necessitor fer:

On Debian/Ubuntu systems, you need to install the python3-venv package using the following command.

$ sudo apt-get install python3-venv
$ python3 -m venv env

Per tant, dins d'aquest entorn no disposo dels paquets que podia tenir en l'entorn normal, com ara numpy.

dins el directori s'ha creat una carpeta env/ que conté una estructura similar a:

├── bin
│   ├── activate
│   ├── activate.csh
│   ├── activate.fish
│   ├── easy_install
│   ├── easy_install-3.5
│   ├── pip
│   ├── pip3
│   ├── pip3.5
│   ├── python -> python3.5
│   ├── python3 -> python3.5
│   └── python3.5 -> /Library/Frameworks/Python.framework/Versions/3.5/bin/python3.5
├── include
├── lib
│   └── python3.5
│       └── site-packages
└── pyvenv.cfg
  • bin: files that interact with the virtual environment
  • include: C headers that compile the Python packages -> a mida que instal·li paquets veuré com es van creant carpetes que fan referència als paquets.
  • lib: a copy of the Python version along with a site-packages folder where each dependency is installed

In order to use this environment’s packages/resources in isolation, you need to activate it. To do this, just run the following:

$ source env/bin/activate
(env) joan@joanHP:~/python-virtual-environments$
(env) joan@joanHP:~/python-virtual-environments$ PS1="E $ " -> canvio el prompt
E $

This is the indicator that env is currently active, which means the python executable will only use this environment’s packages and settings.

Per invocar a python3 no cal fer python3 sinó tan sols python, doncs he instal·lat l'entorn virtual de python3. Per exemple, en aquest entorn virtual, numpy no està disponible (en l'entorn host sí que ho està).

E $ python
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import numpy
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ModuleNotFoundError: No module named 'numpy'

Si volem tornar al system context, hem de desactivar l'entorn virtual:

(env) $ deactivate

En el host:

$ which python
/usr/bin/python

$ which python3
/usr/bin/python3

$ echo $PATH
/home/joan/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

I en l'entorn virtual:

$ source env/bin/activate

E $ which python
/home/joan/python-virtual-environments/env/bin/python

E $ which python3 (és el mateix)
/home/joan/python-virtual-environments/env/bin/python3

E $ echo $PATH
/home/joan/python-virtual-environments/env/bin:/home/joan/.local/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games

Our virtual environment's bin directory is now at the beginning of the path. That means it's the first directory searched when running an executable on the command line. Thus, the shell uses our virtual environment's instance of Python instead of the system-wide version.

This can be explained by how Python starts up and where it is located on the system. There actually isn't any difference between these two Python executables. It's their directory locations that matter.

When Python is starting up, it looks at the path of its binary. In a virtual environment, it is actually just a copy of, or symlink to, your system’s Python binary. It then sets the location of sys.prefix and sys.exec_prefix based on this location, omitting the bin portion of the path.

E $ python
Python 3.6.9 (default, Nov  7 2019, 10:44:02) 
[GCC 8.3.0] on linux
Type "help", "copyright", "credits" or "license" for more information.
>>> import sys
>>> sys.prefix
'/home/joan/python-virtual-environments/env'

Eliminar un entorn virtual

No em queda clar com s'elimina un entorn virtual creat amb la manera de python3. Per tant, ho faré d'aquesat manera (que és també com es fa en el tutorial de tensorflow):

$ virtualenv --system-site-packages -p python3 env1
Already using interpreter /usr/bin/python3
Using base prefix '/usr'
New python executable in /home/joan/projectes/tensorflow_tutorial/env1/bin/python3
Also creating executable in /home/joan/projectes/tensorflow_tutorial/env1/bin/python
Installing setuptools, pip, wheel...
done.

I ara eliminem l'entorn virtual:

$ virtualenv --clear env1
Deleting tree /home/joan/projectes/tensorflow_tutorial/env1/lib/python3.6
Not deleting /home/joan/projectes/tensorflow_tutorial/env1/bin
Using base prefix '/usr'
New python executable in /home/joan/projectes/tensorflow_tutorial/env1/bin/python3
Not overwriting existing python script /home/joan/projectes/tensorflow_tutorial/env1/bin/python (you must use /home/joan/projectes/tensorflow_tutorial/env1/bin/python3)
Installing setuptools, pip, wheel...
done.

Encara queda la carpeta env1. Suposo que puc eliminar-la tal qual

En el tutorial s'explica tot el tema de virtualenvwrapper. Però jo no he fet (l'he hagut de desintal·lar, perquè té ganes de treballar amb python2 i no python3).

utilitzar o no site-packages

$ virtualenv --no-site-packages -p python3 env1
Already using interpreter /usr/bin/python3
...
done.

$ source env1/bin/activate
(env1) ...$ python3 -m pip freeze | grep tensor

No troba res, que és lo correcte. Si hagués utilitzat l'opció system-site-packages, i hagués instal·lat el tensorflow, m'apareixeria en el llistat. I això pot ser una font de conflictes doncs ja no sé què tinc instal·lat en el sistema (host) i en l'entorn virtual.

Per tant, per fer proves amb tensorflow (que és per això que estic aquí), desinstal·lo el tensorflow del sistema.

$ virtualenv --system-site-packages -p python3 env1
Already using interpreter /usr/bin/python3
...
done.

$ source env1/bin/activate