Categorías
Python

Desarrollo basado en pruebas con PYtest

 

Tabla de Contenidos

  • Por qué la necesidad de entornos virtuales?
  • ¿Qué es un entorno virtual?
  • El uso de entornos virtuales
  • ¿Cómo funciona un Entorno Virtual?
  • gestión de entornos virtuales con virtualenvwrapper
  • El uso de diferentes versiones de Python
  • Conclusión

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: de trabajo con Python Virtual Environments

En este artículo, le mostraremos cómo utilizar entornos virtuales para crear y gestionar entornos separados para sus proyectos de Python, cada uno con diferentes versiones de Python para su ejecución. También vamos a echar un vistazo a cómo se almacenan y se resolvieron las dependencias de Python. Bono

gratuito: Haga clic aquí para obtener acceso a una clase gratuita de 5 días de duración que muestra cómo evitar problemas de gestión de la dependencia común con herramientas como Pip, PyPI, virtualenv y archivos requisitos.

  • Actualizado 01/12/2018: pyenv frente a uso clarificada Venv en Python 3.6+
  • Actualización 06/11/2016: Se agregó una sección sobre el cambio de las versiones de Python con virtualenv

Por qué la necesidad de entornos virtuales?

Python, como la mayoría de otros lenguajes de programación modernos, tiene su propia forma de la descarga, el almacenamiento y la resolución de los paquetes (o módulos). Si bien esto tiene sus ventajas, había algunas interesantes decisiones tomadas sobre el almacenamiento de paquetes y resolución, que ha dado lugar a algunos problemas particularmente con cómo y dónde se almacenan los paquetes.

Hay algunos lugares diferentes, donde estos paquetes pueden ser instalados en su sistema. Por ejemplo, la mayoría de los paquetes del sistema se almacenan en un directorio secundario de la ruta almacenada en sys.prefix.

En Mac OS X, se puede encontrar fácilmente en sys.prefix puntos a usar el terminal de Python:

>>> import sys
>>> sys.prefix
'/System/Library/Frameworks/Python.framework/Versions/3.5'

más relevantes al tema de este artículo, paquetes de terceros instaladas usando easy_install o pip normalmente se colocan en uno de los directorios apuntada por site.getsitepackages:

>>> import site
>>> site.getsitepackages()
[
'/System/Library/Frameworks/Python.framework/Versions/3.5/Extras/lib/python',
'/Library/Python/3.5/site-packages'
]

es así, ¿por qué todos estos pequeños detalles asunto?

Es importante saber esto porque, por defecto, todos los proyectos en el sistema utilizará estos mismos directorios para almacenar y recuperar los paquetes sitio (bibliotecas de terceros). A primera vista, esto puede no parecer una gran cosa, y no es verdad, por paquetes del sistema (paquetes que son parte de la biblioteca estándar de Python), pero importa paquetes sitio .

Considere el siguiente escenario donde tendrá dos proyectos: ProjectA y ProjectB , los cuales tienen una dependencia en la misma biblioteca, ProjectC . El problema se hace evidente cuando empezamos que requieren diferentes versiones de ProjectC . Tal vez ProjectA necesita v1.0.0, mientras ProjectB requiere la nueva v2.0.0, por ejemplo.

Este es un problema real para Python, ya que no puede diferenciar entre las versiones en el directorio site-packages. Por lo tanto v1.0.0 y v2.0.0 residirían en el mismo directorio con el mismo nombre:

/System/Library/Frameworks/Python.framework/Versions/3.5/Extras/lib/python/ProjectC

Dado que los proyectos se almacenan de acuerdo con sólo su nombre, no hay diferenciación entre las versiones. Por lo tanto, ambos proyectos, ProjectA y ProjectB , estarían obligados a utilizar la misma versión, lo cual es inaceptable en muchos casos.

Aquí es donde los entornos virtuales y las herramientas virtualenv / Venv entran en juego …

¿Qué es un entorno virtual?

En su esencia, el objetivo principal de los entornos virtuales Python es crear un entorno aislado para proyectos Python. Esto significa que cada proyecto puede tener sus propias dependencias, independientemente de qué dependencias cualquier otro proyecto cuenta.

En nuestro pequeño ejemplo anterior, sólo había necesidad de crear un entorno virtual separado para ambos ProjectA y ProjectB , y que sería bueno para ir. Cada entorno, a su vez, sería capaz de depender de cualquier versión de ProjectC que elijan, independiente de la otra.

Lo bueno de esto es que no hay límites para el número de entornos que puede tener ya que son directorios que contienen sólo unos cuantos scripts. Además, son fácilmente creados usando las herramientas de línea de comandos o virtualenv pyenv.

El uso de entornos virtuales

Para empezar, si no estás usando Python 3, tendrá que instalar la herramienta virtualenv con pip:

$ pip install virtualenv

Si está utilizando Python 3, entonces usted debe tener ya el módulo Venv de la librería estándar instalado.

Nota: De aquí en adelante, asumiremos que está utilizando la herramienta Venv más reciente, ya que hay pocas diferencias entre éste y virtualenv con respecto a las órdenes reales. En realidad, sin embargo, son muy diferentes herramientas.

empezar por hacer un nuevo directorio para el trabajo con:

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

Crear un nuevo entorno virtual dentro del directorio:

# Python 2:
$ virtualenv env

# Python 3
$ python3 -m venv env

Nota: Por defecto, esto no incluir cualquiera de sus paquetes de sitios existentes.

El enfoque de Python 3 Venv tiene la ventaja de obligar a que elija una versión específica del intérprete de Python 3 que se debe utilizar para crear el entorno virtual. Esto evita cualquier confusión en cuanto a que la instalación de Python el nuevo entorno se basa en.

Desde Python 3.3 a 3.4, la forma recomendada para crear un entorno virtual era utilizar la herramienta de línea de comandos pyvenv que también viene incluido con la instalación de Python 3 por defecto. Pero en 3.6 y superiores, python3 -m Venv es el camino a seguir.

En el ejemplo anterior, este comando crea un directorio llamado env, que contiene una estructura de directorios similar a esto:

├── 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

Esto es lo que contiene cada carpeta: bin

  • : archivos que interactúan con el entorno virtual
  • incluyen: C cabeceras que compilan el pitón paquetes
  • lib: una copia de la versión de Python junto con un sitio de paquetes carpeta donde cada dependencia se instala

además, hay copias o enlaces simbólicos a, algunas herramientas de Python diferentes, así como a la pitón ejecutables sí mismos. Estos archivos se utilizan para asegurar que todo el código Python y comandos se ejecutan en el contexto del entorno actual, que es como se logra el aislamiento del medio ambiente mundial. Vamos a explicar esto con más detalle en la siguiente sección.

Más interesantes son las secuencias de comandos Activar en el directorio bin. Estas secuencias de comandos se utilizan para configurar su cáscara para utilizar Python ejecutable del medio ambiente y sus site-packages por defecto.

Para utilizar paquetes / recursos de este entorno de forma aislada, lo que necesita para “activar” la misma. Para ello, basta con ejecutar la siguiente:

$ source env/bin/activate
(env) $

Aviso cómo su pronta ahora se puede anteponer el nombre de su entorno (env, en nuestro caso). Este es el indicador que env está actualmente activo, lo que significa que el ejecutable pitón sólo utilizará paquetes y configuraciones de este entorno.

Para mostrar el aislamiento paquete en la acción, podemos utilizar el módulo bcrypt como un ejemplo. Digamos que tenemos bcrypt instalada en todo el sistema, pero no en nuestro entorno virtual.

Antes de probar esto, tenemos que volver al contexto “sistema” de desactivación de ejecución:

(env) $ deactivate
$

Ahora su sesión de shell es volver a la normalidad, y el comando python se refiere a la instalación de Python mundial. Recuerda hacer esto cada vez que haya terminado de usar un entorno virtual específico.

Ahora, instalar bcrypt y lo utilizan para hash de una contraseña:

$ pip -q install bcrypt
$ python -c "import bcrypt; print(bcrypt.hashpw('password'.encode('utf-8'), bcrypt.gensalt()))"
$2b$12$vWa/VSvxxyQ9d.WGgVTdrell515Ctux36LCga8nM5QTW0.4w8TXXi

Esto es lo que sucede si tratamos el mismo comando cuando se activa el entorno virtual:

$ source env/bin/activate
(env) $ python -c "import bcrypt; print(bcrypt.hashpw('password'.encode('utf-8'), bcrypt.gensalt()))"
Traceback (most recent call last):
File "", line 1, in
ImportError: No module named 'bcrypt'

Como se puede ver, el comportamiento de la pitón -c «import bcrypt …» cambios de mando después de la fuente de env / bin / llamada de activación.

En un caso, tenemos bcrypt a nuestra disposición, y en el siguiente no lo hacen. Este es el tipo de separación que estamos buscando lograr con entornos virtuales, que ahora es fácil de lograr.

¿Cómo funciona un entorno virtual?

¿Qué es exactamente lo que significa “activar” un entorno? Saber lo que está pasando bajo el capó puede ser muy importante para un desarrollador, especialmente cuando es necesario comprender entornos de ejecución, resolución de dependencias, y así sucesivamente.

Para explicar cómo funciona este, el primer cheque de dejar salir el ubicaciones de los diferentes ejecutables pitón. Con el medio ambiente “desactivado”, ejecute el siguiente:

$ which python
/usr/bin/python

Ahora, activarlo y ejecutar el comando:

$ source env/bin/activate
(env) $ which python
/Users/michaelherman/python-virtual-environments/env/bin/python

Después de activar el medio ambiente, ahora estamos consiguiendo un camino diferente para el ejecutable de Python, ya que, en un ambiente activo , la variable de entorno $ PATH se modifica ligeramente.

cuenta de la diferencia entre el primer camino en $ PATH antes y después de la activación:

$ echo $PATH
/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:

$ source env/bin/activate
(env) $ echo $PATH
/Users/michaelherman/python-virtual-environments/env/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin:

En este último ejemplo, el directorio bin de nuestro entorno virtual está ahora en el comienzo del camino. Eso significa que es el primer anuario buscó cuando se ejecuta un archivo ejecutable en la línea de comandos. Por lo tanto, el shell utiliza ejemplo de nuestro entorno virtual de Python en lugar de la versión de todo el sistema.

Nota: Otros paquetes de ese paquete de Python, como Anaconda, también tienden a manipular su camino cuando las activas. Acaba de ser conscientes de esto en caso de que tenga problemas con sus otros entornos. Esto puede convertirse en un problema si se inicia la activación de múltiples entornos a la vez.

Esto plantea las siguientes preguntas:

  • ¿Cuál es la diferencia entre estos dos ejecutables de todos modos?
  • Cómo es Python del entorno virtual ejecutable capaz de usar algo distinto site-packages del sistema?

Esto puede explicarse por la forma en Python se pone en marcha y donde se encuentra en el sistema. Hay en realidad no hay ninguna diferencia entre estos dos ejecutables Python. Es sus ubicaciones del directorio de esa materia.

Cuando Python se está iniciando, se ve en el camino de su binario. En un entorno virtual, en realidad es sólo una copia o enlace simbólico, Python binaria del sistema. A continuación, establece la ubicación de sys.prefix y sys.exec_prefix basado en esta ubicación, omitiendo la parte de bin de la ruta.

El camino situado en sys.prefix se utiliza para localizar el directorio site-packages buscando en la ruta relativa lib / pythonX.X / site-packages /, donde X.X es la versión de Python que esté utilizando.

En nuestro ejemplo, el binario se encuentra en / Usuarios / michaelherman / pitón de virtual entornos / env / bin, lo que significa sys.prefix sería / Usuarios / michaelherman /-pitón virtual-ambientes / env, y por lo tanto el sitio -packages directorio utilizado sería /Users/michaelherman/python-virtual-environments/env/lib/pythonX.X/site-packages. Por último, este camino se almacena en la matriz sys.path, que contiene todos los lugares en los que un paquete puede residir.

gestión de entornos virtuales con virtualenvwrapper

Mientras entornos virtuales sin duda a resolver algunos grandes problemas con la gestión de paquetes, no son perfectos. Después de crear unos entornos, usted comenzará a ver que crean algunos problemas por sí mismos, la mayoría de las cuales giran en torno a la gestión de los propios entornos. Para ayudar con esto, se ha creado la herramienta virtualenvwrapper. Es tan sólo de algunos scripts de todo el instrumento principal virtualenv.

Algunas de las características más útiles de virtualenvwrapper son que:

  • organiza todos sus entornos virtuales en un solo lugar
  • proporciona métodos para ayudarle a fácilmente crear, eliminar y copiar entornos
  • proporciona un único comando para cambiar entre los entornos

Si bien algunas de estas características puede parecer pequeña o insignificante, pronto aprenderá que son herramientas importantes para añadir a su flujo de trabajo.

Para empezar, se puede descargar la envoltura con pip:

$ pip install virtualenvwrapper

Nota: Para Windows, debe utilizar virtualenvwrapper-ganar su lugar.

Una vez instalado, tendremos que activar sus funciones de shell. Podemos hacer esto mediante la ejecución de código en el guión virtualenvwrapper.sh instalado. Cuando se instala por primera vez con el PIP, la salida de la instalación le indicará la ubicación exacta de virtualenvwrapper.sh . O simplemente puede ejecutar el siguiente:

$ which virtualenvwrapper.sh
/usr/local/bin/virtualenvwrapper.sh

Usando ese camino, añadir las siguientes tres líneas al archivo de inicio del shell. Si está utilizando el shell Bash, colocaría estas líneas, ya sea en el archivo ~ / .bashrc o el archivo ~ / .profile. Para otros proyectiles, como zsh, CSH, o pescado, que tendría que utilizar la específica archivos de inicio a la cáscara. Lo único que importa es que estos comandos se ejecutan cuando se conecte o se abre un nuevo shell:

export WORKON_HOME=$HOME/.virtualenvs # Optional
export PROJECT_HOME=$HOME/projects # Optional
source /usr/local/bin/virtualenvwrapper.sh

Nota: No es necesario definir el WORKON_HOME y variables de entorno PROJECT_HOME. virtualenvwrapper tiene valores por defecto de ellos, pero se puede anular mediante la definición de los valores.

Por último, volver a cargar el archivo de inicio:

$ source ~/.bashrc

Ahora debe haber un directorio ubicado en $ WORKON_HOME que contiene todos los datos / archivos virtualenvwrapper:

$ echo $WORKON_HOME
/Users/michaelherman/.virtualenvs

Además, ahora podrá disponer de comandos disponibles de Shell para usted para ayudarle a manejar los entornos. Éstos son sólo algunos de los que están disponibles:

  • workon
  • Desactivar
  • mkvirtualenv
  • cdvirtualenv
  • rmvirtualenv

Para obtener más información sobre los comandos, la instalación y la configuración de virtualenvwrapper, echa un vistazo a la documentación.

Ahora, cada vez que desee iniciar un nuevo proyecto, sólo hay que hacer esto:

$ mkvirtualenv my-new-project
(my-new-project) $

Esto creará y activar un nuevo entorno en el directorio ubicado en $ WORKON_HOME, donde se almacenan todos los entornos virtualenvwrapper.

Para dejar de utilizar ese medio, sólo tiene que desactivarlo como antes:

(my-new-project) $ deactivate
$

Si usted tiene muchos ambientes para elegir, puede listar todos ellos con la función workon:

$ workon
my-new-project
my-django-project
web-scraper

Por último, aquí está cómo activar:

$ workon web-scraper
(web-scraper) $

Si le gustaría ser capaz de utilizar una única herramienta y cambiar entre versiones de Python, virtualenv le permitirá hacer precisamente eso. virtualenv tiene una -p parámetro que le permite seleccionar qué versión de Python para su uso. Combine eso con el comando which, y podemos seleccionar fácilmente su versión preferida de Python para su uso de una manera sencilla. Por ejemplo, digamos que queremos Python 3 como nuestra versión preferida:

$ virtualenv -p $(which python3) blog_virtualenv

Esto creará un nuevo entorno Python 3.

¿Cómo funciona esto? El comando de la cual se utiliza para la búsqueda de una orden dada en la variable $ PATH y devolver la ruta completa a ese comando. Por lo tanto, se devolvió la ruta completa a python3, con el parámetro -p que toma un PYTHON_EXE. Esto también podría ser utilizado para python2 también. python3 simplemente sustituto de python2 (o pitón en caso de insolvencia del sistema para que python2).

Ahora usted no tiene que recordar donde instaló sus entornos. Puede eliminar fácilmente o copiarlos como desee, y su directorio de proyecto es menos desordenada!

El uso de diferentes versiones de Python

A diferencia de la herramienta virtualenv de edad, pyvenv no admite la creación de entornos con versiones arbitrarias de Python, que está atrapado medios utilizando el 3 de instalación por defecto de Python para todos los ambientes que se crean. Si bien se puede actualizar un entorno a la última versión del sistema de Python (a través de la opción –upgrade), si cambia, todavía puede en realidad no especificar una versión particular.

Hay bastantes formas de instalar Python, pero pocos de ellos son bastante fácil o lo suficientemente flexible como para frecuencia desinstale y vuelva a instalar diferentes versiones de la binaria.

Aquí es donde entra en juego pyenv a juego.

A pesar de la similitud en los nombres (pyvenv vs pyenv), pyenv es diferente, ya que su objetivo es ayudar a cambiar entre versiones de Python en un nivel de sistema, así como a nivel de proyecto. Mientras que el propósito de pyvenv es separar los módulos, el propósito de pyenv es separar versiones Python.

Puede comenzar con la instalación de pyenv, ya sea con Homebrew (en OS X) o el proyecto pyenv-instalador:

Homebrew

$ brew install pyenv

pyenv-instalador

$ curl -L https://raw.githubusercontent.com/yyuu/pyenv-installer/master/bin/pyenv-installer | bash

Nota: Desafortunadamente, pyenv no es compatible con Windows . Unas pocas alternativas para intentar son pywin y anyenv.

Una vez que tenga pyenv en su sistema, aquí están algunos de los comandos básicos es probable que estés interesado en:

$ pyenv install 3.5.0 # Install new version
$ pyenv versions # List installed versions
$ pyenv exec python -V # Execute 'python -V' using pyenv version

En estas pocas líneas, se instala la versión 3.5.0 de Python, pregunte pyenv para mostrarnos todos las versiones disponibles para nosotros, y luego ejecutar el comando python -V utilizando la versión pyenv-especificado.

para darle aún más control, a continuación, puede utilizar cualquiera de las versiones disponibles para su uso, ya sea “global” o de “condiciones locales”. Usando pyenv con los conjuntos de comandos locales la versión de Python para un proyecto o directorio específico almacenando el número de versión de un archivo local .python versión . Podemos establecer la versión “local” de esta manera:

$ pyenv local 2.7.11

Esto crea el archivo .python versión en nuestro directorio actual, como se puede ver aquí:

$ ls -la
total 16
drwxr-xr-x 4 michaelherman staff 136 Feb 22 10:57 .
drwxr-xr-x 9 michaelherman staff 306 Jan 27 20:55 ..
-rw-r--r-- 1 michaelherman staff 7 Feb 22 10:57 .python-version
-rw-r--r-- 1 michaelherman staff 52 Jan 28 17:20 main.py

Este archivo sólo contiene los contenidos “2.7.11”. Ahora, cuando se ejecuta una secuencia de comandos con pyenv, que va a cargar este archivo y utilizar la versión especificada, asumiendo que es válida y existe en el sistema.

seguir adelante con nuestro ejemplo, supongamos que tenemos un script sencillo llamado main.py en nuestro directorio proyecto que es similar al siguiente:

import sys
print('Using version:', sys.version[:5])

Todo lo que hace es imprimir el número de versión del ser ejecutable de Python utilizada. Usando pyenv y el comando exec, podemos ejecutar el script con cualquiera de las diferentes versiones de Python que hemos instalado.

$ python main.py
Using version: 2.7.5
$ pyenv global 3.5.0
$ pyenv exec python main.py
Using version: 3.5.0
$ pyenv local 2.7.11
$ pyenv exec python main.py
Using version: 2.7.11

Observe cómo pyenv ejecutivo pitón main.py utiliza nuestra versión “global” Python por defecto, pero entonces se usa la versión “local” después de que uno se fija para el directorio actual.

Esto puede ser muy poderosa para los desarrolladores que tienen un montón de proyectos con distintos requisitos de la versión. No sólo se puede cambiar fácilmente la versión por defecto para todos los proyectos (mediante global), pero también se puede anularlo para especificar casos especiales.

Conclusión

En este artículo, usted aprendió sobre no sólo cómo se almacenan y se resolvieron las dependencias de Python, sino también cómo se pueden utilizar diferentes herramientas de la comunidad para ayudar a conseguir alrededor de una variedad de envases y los problemas de control de versiones.

Como se puede ver, gracias a la comunidad enorme pitón, hay un buen número de herramientas a su disposición para ayudar con estos problemas comunes. A medida que avance como desarrollador, asegúrese de tomar el tiempo para aprender a utilizar estas herramientas para su ventaja. Usted puede incluso encontrar usos no previstos para ellos o aprender a aplicar los conceptos similares a otros idiomas que utiliza. Bono

gratuito: Haga clic aquí para obtener acceso a una clase gratuita de 5 días de duración que muestra cómo evitar problemas de gestión de la dependencia común con herramientas como Pip, PyPI, virtualenv y archivos requisitos.

Esta es una pieza colaboración entre Scott Robinson, autor de la pila Abuso y la gente en el Real Python.

Mira ahora Este tutorial tiene un vídeo relacionado curso creado por el equipo del Real Python. Mira que junto con el tutorial escrito para profundizar su comprensión: de trabajo con Python Virtual Environments

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *