from - ¿Cómo anteponer una ruta a sys.path en Python?
reinstall pip (8)
El uso de virtualenv causaría una cantidad innecesaria de cambios en mi máquina, ya que tendría que reinstalar cada paquete que existe globalmente. Solo quiero actualizar los paquetes de Ubuntu a los paquetes de pip.
No, puedes usar --system-site-packages
.
Editar
# make your new virtualenv
user@darkstar:~$ mkvirtualenv --system-site-packages max
(max)user@darkstar:~$ python
>>> pprint(sys.path)
['''',
''/home/user/.virtualenvs/max/lib64/python27.zip'',
''/home/user/.virtualenvs/max/lib64/python2.7'',
''/home/user/.virtualenvs/max/lib64/python2.7/plat-linux2'',
''/home/user/.virtualenvs/max/lib64/python2.7/lib-tk'',
''/home/user/.virtualenvs/max/lib64/python2.7/lib-old'',
''/home/user/.virtualenvs/max/lib64/python2.7/lib-dynload'',
''/usr/lib64/python2.7'',
''/usr/lib/python2.7'',
''/usr/lib64/python2.7/lib-tk'',
''/home/user/.virtualenvs/max/lib/python2.7/site-packages'',
''/usr/lib64/python2.7/site-packages/google_api_python_client-1.2-py2.7.egg'',
''/usr/lib64/python2.7/site-packages'',
''/usr/lib64/python2.7/site-packages/PIL'',
''/usr/lib64/python2.7/site-packages/gtk-2.0'',
''/usr/lib64/python2.7/site-packages/IPython/extensions'']
Como ves, la ruta de este virtualenv incluye la ruta del sistema. Para comprobar si funcionaba, instalé un paquete en todo el sistema después de hacer el virtualenv.
root@darkstar:~: pip install igraph
Collecting igraph
Downloading igraph-0.1.8-py2.py3-none-any.whl (119kB)
100% |████████████████████████████████| 122kB 1.7MB/s
Collecting ipython (from igraph)
Downloading ipython-3.2.1-py2-none-any.whl (3.4MB)
100% |████████████████████████████████| 3.4MB 203kB/s
Installing collected packages: ipython, igraph
Successfully installed igraph-0.1.8 ipython-3.2.1
root@darkstar:~: python -c ''print __import__("igraph")''
<module ''igraph'' from ''/usr/lib64/python2.7/site-packages/igraph/__init__.pyc''>
(max)user@darkstar:max$ python -c ''print __import__("igraph")''
<module ''igraph'' from ''/usr/lib64/python2.7/site-packages/igraph/__init__.pyc''>
Obviamente, lo que se instala dentro de virtualenv tiene prioridad sobre las bibliotecas de todo el sistema.
Creo que respondo a tus necesidades.
Descripción del problema:
Usando pip, actualicé a la última versión de las requests (versión 2.7.0, con pip show requests
dan la ubicación /usr/local/lib/python2.7/dist-packages
). Sin embargo, al import requests
e imprimir requests.__version__
en la línea de comandos interactiva, estoy viendo la versión 2.2.1. Resulta que Python está utilizando la versión de solicitudes de Ubuntu preinstalada (las requests.__file__
es requests.__file__
- no /user/local/lib/...
).
A partir de mi investigación, este hecho se debe a los cambios de Ubuntu en la ruta de búsqueda de Python (yo ejecuto Ubuntu 14.04) al anteponer la ruta al paquete de Ubuntu Python (para mi máquina, esto sucede en usr/local/lib/python2.7/dist-packages/easy-install.pth
). En mi caso, esto hace que se use la versión de solicitudes apt-get
, que está preempaquetada con Ubuntu, en lugar de la versión pip que quiero usar.
Lo que estoy buscando:
Quiero anteponer globalmente la ruta del directorio de instalación de pip a la ruta de búsqueda de Python ( sys.path
), antes de la ruta al directorio de instalación de Ubuntu Python. Dado que las solicitudes (y muchos otros paquetes) se usan en muchos de mis scripts de Python, no quiero cambiar manualmente la ruta de búsqueda para cada archivo en mi máquina.
Solución insatisfactoria 1: Uso de virtualenv
El uso de virtualenv causaría una cantidad innecesaria de cambios en mi máquina, ya que tendría que reinstalar cada paquete que existe globalmente. Solo quiero actualizar los paquetes de Ubuntu a los paquetes de pip.
Solución insatisfactoria 2: cambio de fácil instalación.pth
Debido easy-install.pth
se sobrescribe easy-install.pth
cada vez que se usa easy-install
, mis cambios a easy-install.pth
se eliminarán si se instala un nuevo paquete. Este problema hace que sea difícil mantener los paquetes en mi máquina.
Insatisfactorio (pero el mejor que tengo hasta ahora) Solución 3: Agregar un archivo .pth separado
En el mismo directorio que easy-install.pth, agregué un zzz.pth
con contenido:
import sys; sys.__plen = len(sys.path)
/usr/lib/python2.7/dist-packages/test_dir
import sys; new=sys.path[sys.__plen:]; del sys.path[sys.__plen:]; p=getattr(sys,''__egginsert'',0); sys.path[p:p]=new; sys.__egginsert = p+len(new)
site.py
lee este archivo cuando se inicia Python. Dado que su nombre de archivo aparece después de easy-install.pth
alfanuméricamente, se consume en site.py
posteriormente. Tomadas en conjunto, las primeras y últimas líneas del archivo anteponen la ruta a sys.path
(estas líneas se tomaron de easy-install.pth
).
No me gusta cómo esta solución depende del orden alfanumérico del nombre del archivo para colocar correctamente la nueva ruta.
PYTHONPATHs vienen después de los caminos de Ubuntu
Otra respuesta en Stack Overflow no funcionó para mí. Mis rutas PYTHONPATH
vienen después de las rutas en easy-install.pth
, que usa el mismo código que menciono en "Solución insatisfactoria 3" para anteponer sus rutas.
¡Gracias de antemano!
Responder a la pregunta directa
Podría crear un directorio llamado sitecustomize
en su directorio de site-packages
. sitecustomize
esto en un módulo de personalización de sitio como se describe here (Python 2 here ). Específicamente:
se intenta importar un módulo llamado sitecustomize, que puede realizar personalizaciones arbitrarias específicas del sitio. Normalmente lo crea un administrador del sistema en el directorio de paquetes de sitio.
En el directorio de sitecustomize
, cree un archivo llamado __init__.py
y agregue las manipulaciones que desea realizar allí. Un ejemplo muy simple es:
import sys
sys.path = [''/your/path/to/pip/install''] + sys.path
En su caso, creo que your/path...
sería /usr/local/lib/python2.7/dist-packages
. Es posible que desee hacer algo más sofisticado, pero esto se compara crudamente con sys.path
y se ejecuta cada vez que se inicia python (por ejemplo, iniciar el intérprete en la línea de comandos o ejecutar un script de python desde un archivo).
Advertencia
No soy un gran defensor de hacer esto, es una forma un tanto directa de hacer lo que quiere. Pero específicamente dice que usar un virtualenv
es indeseable para usted y quiere hacer el cambio "globalmente" y creo que esto hará lo que quiera.
Reflexiones sobre el tema subyacente.
Creo que la answer de @fivetentaylor está en el camino correcto aquí: parece que estás usando pip
de una instalación con el ejecutable de python
para otra. Enmascarar esto jugando con el camino podría ser muy confuso muy rápidamente. Definitivamente me aseguraré de que tengas un pip
separado para cada instalación de python
y lo uses. Eso debería mantener separadas las estructuras de directorios para las instalaciones separadas. De lo contrario, está obligando a una instalación a usar paquetes de directorios de una instalación diferente. No hay problema técnico, pero confuso logísticamente.
A partir de los sonidos de las cosas, Ubuntu está utilizando un archivo de configuración de ruta de paquete como se documenta here para configurar cualquier paquete que instale.
Mirando site.py veo que hay un orden específico de resolución de ruta que invoca los archivos de configuración a medida que resuelve los directorios de paquetes del sitio.
Creo que eso te da tres opciones que puedo ver:
- Use virtualenv --system-site-packages según la respuesta de @ffh.
- Use las instalaciones de usuario de pip para configurar los paquetes que necesita en la ruta antes de los paquetes de sitio estándar.
- Utilice sitecustomize para volver a escribir su sys.path (por ejemplo, para poner primero los directorios locales).
Bueno, las alternativas presentadas por los demás son muy aceptables e incluso podrían ser mejores. Sin embargo, si tiene la intención de usar la forma sys.path()
, entonces trátela como una lista y use el método de inserción.
import sys
sys.path.insert(0, "path_to_pip")
from subprocess import call
call("sudo pip install requests")
Esto no se recomienda *, pero desde tu script en Python puedes hacerlo
>>> import sys
>>> b = sys.path
>>> sys.path = [''/home/anand/''] + b
>>> print(sys.path)
[''/home/anand/'', '''', ''/usr/local/lib/python2.7/dist-packages/_pdbpp_path_hack'', ''/usr/local/lib/python2.7/dist-packages/goose-0.0.1-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/jieba-0.33-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/cssselect-0.9.1-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/nanoservice-0.1.5-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/nanomsg-1.0a2-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/msgpack_python-0.4.2-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/DecisionTree-2.2.5-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/nudepy-0.2-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/wsgilog-0.3-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/distribute-0.7.3-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/PIL-1.1.7-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/MySQL_python-1.2.5-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/munkres-1.0.7-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/parsedatetime-1.4-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/argparse-1.3.0-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/tusker-0.1-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/SQLAlchemy-1.0.3-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/numpy-1.9.2-py2.7-linux-x86_64.egg'', ''/usr/local/lib/python2.7/dist-packages/turkic-0.2.5-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/scikits.bootstrap-0.3.2-py2.7.egg'', ''/usr/local/lib/python2.7/dist-packages/pyvision-0.1-py2.7-linux-x86_64.egg'', ''/home/anand/playspace/languages/python_pkgs/ets'', ''/usr/local/lib/python2.7/dist-packages/Scrapy-1.1.0dev1-py2.7.egg'', ''/usr/lib/python2.7/dist-packages'', ''/home/anand/playspace'', ''/home/anand/workspace/pyvision/src'', ''/home/anand/playspace/yapf'', ''/usr/lib/python2.7'', ''/usr/lib/python2.7/plat-x86_64-linux-gnu'', ''/usr/lib/python2.7/lib-tk'', ''/usr/lib/python2.7/lib-old'', ''/usr/lib/python2.7/lib-dynload'', ''/usr/local/lib/python2.7/dist-packages'', ''/usr/local/lib/python2.7/dist-packages/Orange/orng'', ''/usr/local/lib/python2.7/dist-packages/PIL'', ''/usr/lib/python2.7/dist-packages/PILcompat'', ''/usr/lib/python2.7/dist-packages/gst-0.10'', ''/usr/lib/python2.7/dist-packages/gtk-2.0'', ''/usr/lib/pymodules/python2.7'', ''/usr/lib/python2.7/dist-packages/wx-3.0-gtk2'']
>>>
Después de esto, sus importaciones buscarán la ruta de acceso precedida antes de buscar en otro lugar.
- - Para la codificación de la ruta y la incapacidad del script para ejecutarse en cualquier otro lugar.
Haría esto con sitecustomize
como se describe en los documentos de site.py
Este archivo se importa después de configurar sys.path
inicial y puede usarlo para modificar sys.path
de maneras arbitrarias, según sea necesario.
Lo he usado como administrador de sistemas para incluir ubicaciones de lanzamiento personalizadas y hace el trabajo bastante bien.
No deberías tener que meterte en la ruta de pip, Python en realidad se maneja automáticamente en mi experiencia. Parece que tienes dos pitones instalados. Si escribe:
which pip
which python
que caminos ves Si no están en la misma carpeta / bin, entonces ese es tu problema. Supongo que el Python que está ejecutando (probablemente el sistema original), no tiene su propio pip instalado. Probablemente solo necesite asegurarse de que la ruta para el Python que desea ejecutar debe aparecer antes de / usr / bin en su .bashrc o .zshrc
Si esto es correcto, entonces deberías ver que:
which easy_install
comparte la misma ruta que la instalación de Python que está utilizando, tal vez en / usr / local / bin. Entonces simplemente ejecuta:
easy_install pip
Y comienza a instalar los paquetes correctos para el pitón que estás usando.
Si respuesta resolverá tu problema ahora, es probable que encuentres algún otro paquete en el que no quieras usar la versión provista por Ubuntu. Así que aquí está la razón por la que desea utilizar los virtualenvs para administrar las versiones de los paquetes (y no tratar de anular las versiones del sistema).
Como ha notado, el orden de sys.path establece el orden en que se encuentran los paquetes de Python. Esto significa que cambiar sys.path afecta la forma en que los scripts de Python encuentran sus importaciones, tanto los scripts que ha escrito como los que proporciona Ubuntu . Dado que los scripts de Python se usan en los programas de Ubuntu, es posible "romper" Ubuntu de formas interesantes cambiando la versión de los paquetes de python que usan los programas de Ubuntu (que es la razón por la que existen los paquetes dist).
Para evitar esto, se creó virtualenv, que efectivamente permite que se utilicen diferentes conjuntos de paquetes. Ahora hay un montón de utilidades que facilitan el uso y la administración de virtualenvs. El que probablemente sea de mayor interés para usted es pipsi , que crea un virtualv por script y evita la necesidad de activarlo.