2012-04-10 22 views
73

Editar: basado en un comentario de Ulf Rompe, es importante que use "1" en lugar de "0", de lo contrario, va a romper sys.path.¿Por qué usar sys.path.append (ruta) en lugar de sys.path.insert (1, ruta)?

He estado haciendo python durante bastante tiempo (más de un año), y siempre estoy confundido de por qué las personas recomiendan que use sys.path.append() en lugar de sys.path.insert(). Déjame demostrar.

Digamos que estoy trabajando en un módulo llamado PyWorkbooks (que está instalado en mi computadora), pero estoy trabajando simultáneamente en un módulo diferente (digamos PyJob) que incorpora PyWorkbooks. Mientras estoy trabajando en PyJob encuentro errores en PyWorkbooks que estoy corrigiendo, así que me gustaría importar una versión de desarrollo.

Hay varias maneras de trabajar en ambas (podría poner mi proyecto de PyWorkbooks dentro de PyJob, por ejemplo), pero a veces todavía necesitaré jugar con la ruta. Sin embargo, no puedo simplemente hacer un sys.path.append() en la carpeta donde está PyWorkbooks en. ¿Por qué? ¡Porque Python encontrará primero mis PyWorkbooks instalados!

Esto es por lo que tiene que hacer un sys.path.insert (1, path_to_dev_pyworkbooks)

En resumen:

sys.path.append(path_to_dev_pyworkbooks) 
import PyWorkbooks # does NOT import dev pyworkbooks, imports installed one 

o:

sys.path.insert(1, path_to_dev_pyworkbooks) # based on comments you should use **1 not 0** 
import PyWorkbooks # imports correct file 

Esto ha causado más de una Hangups para mí en el pasado, y realmente me gustaría si nosotros (como comunidad) comenzáramos a recomendar sys.path.insert(1, path), como si estuviera insertando manualmente una ruta, creo que es seguro decir que ese es el camino ¡quieres usar!

¿O tengo algo mal? ¡Es una pregunta que a veces me molesta y lo quería abiertamente!

+1

I've done 's ys.path.insert (1, dev_folder) 'pero aún no encuentra el módulo dev, y solo usa el módulo instalado. ¿Cómo puedo solucionar esto? – endolith

Respuesta

40

Si tiene varias versiones de un paquete/módulo, hay que estar usando virtualenv (el énfasis es mío):

virtualenv es una herramienta para crear entornos Python aisladas.

El problema básico que se trata es una de dependencias y versiones, y permisos indirectos. Imagine que tiene una aplicación que necesita la versión 1 de LibFoo, pero otra aplicación requiere la versión 2. ¿Cómo puede usar ambas aplicaciones? Si instala todo en /usr/lib/python2.7/site-packages (o cualquiera que sea la ubicación estándar de su plataforma), es fácil terminar en una situación en la que involuntariamente actualice una aplicación que no debe actualizarse.

O más en general, ¿qué ocurre si desea instalar una aplicación y déjelo en? Si una aplicación funciona, cualquier cambio en sus bibliotecas o las versiones de esas bibliotecas pueden romper la aplicación.

Además, ¿qué ocurre si no puede instalar paquetes en el directorio global site-packages? Por ejemplo, en un host compartido.

En todos estos casos, virtualenv puede ayudarlo.Crea un entorno que tiene sus propios directorios de instalación, que no comparte bibliotecas con otros entornos Virtualenv (y opcionalmente tampoco tiene acceso a las bibliotecas instaladas globalmente).

Es por eso que la gente considera insert(0, estar equivocado - es una solución incompleta, provisional al problema de la gestión de múltiples entornos.

+0

Gracias, vagamente sabía que algo así existía, pero hasta ahora no lo había comprobado. Entonces, lo que tendría que hacer con esto es ejecutar todo, desde el intérprete en el entorno virtual ... eso podría funcionar también. ¡Gracias! –

37

Si realmente necesita usar sys.path.insert, dejar que sys.path [0] como es:

sys.path.insert(1, path_to_dev_pyworkbooks) 

Esto podría ser importante ya que el código tercera parte puede depender de conformidad sys.path documentation:

Como se ha inicializado en el inicio del programa, el primer elemento de esta lista, camino [0], es el directorio que contiene la secuencia de comandos que se utilizó para invocar el intérprete de Python.

12

está confundiendo el concepto de agregar y anteponer. el siguiente código se prepending:

sys.path.insert(1,'/thePathToYourFolder/') 

se coloca la nueva información al principio (así, en segundo lugar, para ser exactos) de la secuencia de búsqueda que su intérprete pasará a través. sys.path.append() coloca las cosas al final de la secuencia de búsqueda.

es aconsejable que utilice algo como virtualenv en lugar de codificar manualmente los directorios de sus paquetes en el PYTHONPATH cada vez. para la creación de diversos ecosistemas que separan sus site-packages y las posibles versiones de pitón, lea estos dos blogs:

  1. python ecosystems introduction

  2. bootstrapping python virtual environments

si decide bajar el camino hacia el aislamiento del medio ambiente que sin duda se beneficiaría al buscar en virtualenvwrapper: http://www.doughellmann.com/docs/virtualenvwrapper/

Cuestiones relacionadas