web-dev-qa-db-ja.com

Pythonでsys.pathへのパスを追加する方法は?

問題の説明:

Pipを使用して、最新バージョンの requests にアップグレードしました(バージョン2.7.0、pip show requestsに場所/usr/local/lib/python2.7/dist-packagesを指定)。ただし、対話型コマンドラインでimport requestsを出力し、requests.__version__を出力すると、バージョン2.2.1が表示されます。 PythonはプレインストールされたUbuntuバージョンのリクエストを使用していることがわかります(requests.__file__/usr/lib/python2.7/dist-packages/requests/__init__.pyc-/user/local/lib/...ではありません)。

私の調査によると、この事実はUbuntuのPython検索パス(Ubuntu 14.04を実行しています)へのパスをUbuntuのPythonパッケージ(私のマシンでは、これはusr/local/lib/python2.7/dist-packages/easy-install.pthで発生します。私の場合、これにより、使用したいpipバージョンではなく、Ubuntuに事前にパッケージ化されたapt-getバージョンのリクエストが使用されます。 。

私が探しているもの:

UbuntuのPythonインストールディレクトリへのパスの前に、Pythonの検索パス(sys.path)へのpipのインストールディレクトリパスをグローバルに追加します。リクエスト(および他の多くのパッケージ)は多くのPython私のスクリプト、私のマシン上のすべてのファイルの検索パスを手動で変更したくありません。

不十分なソリューション1:virtualenvの使用

virtualenv を使用すると、グローバルに存在するすべてのパッケージを再インストールする必要があるため、マシンに不要な変更が発生します。 Ubuntuのパッケージからpipのパッケージにアップグレードしたいだけです。

不十分なソリューション2:easy-install.pthの変更

easy-install.pthを使用するたびにeasy-installが上書きされるため、新しいパッケージをインストールすると、easy-install.pthへの変更が削除されます。この問題により、私のマシンでパッケージを維持することが困難になっています。

不十分(ただし、これまでのところ最高のもの)解決策3:別の.pthファイルを追加する

Easy-install.pthと同じディレクトリにzzz.pthと内容を追加しました:

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)

このファイルは、Pythonの開始時にsite.pyによって読み取られます。ファイル名はeasy-install.pthの後に英数字が続くため、site.pyによって後で消費されます。一緒に取得、ファイルの最初と最後の行はsys.pathへのパスを付加します(これらの行はeasy-install.pthから取得されました)。

この解決策が新しいパスを正しく配置するためにファイル名の英数字の順序に依存するのが好きではありません。

PYTHONPATHはUbuntuのパスの後に来ます

別の回答 スタックオーバーフローで動作しませんでした。私のPYTHONPATHパスはeasy-install.pthのパスの後にあります。これは、「不満足なソリューション3」で言及したのと同じコードを使用してパスを先頭に追加します。

よろしくお願いします!

24
max

これはパスをハードコーディングし、他の場所でスクリプトを実行することを困難にするため、お勧めできませんが、

>>> import sys
>>> sys.path.insert(0,'/home/anand/')
>>> 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']
>>>

この後、インポートは他の場所を探す前に、先頭に追加されたパスを調べます。

13
Nandhini Anand

あなたはpipのパスをいじる必要はありません、pythonは実際には私の経験で自動的にパスを処理します。 2つのpythonがインストールされているようです。入力した場合:

which pip
which python

どんな道が見えますか?それらが同じ/ binフォルダーにない場合は、それが問題です。あなたが実行しているpython(おそらく元のシステムの1つ)には、独自のpipがインストールされていないと思います。おそらく、実行するpythonのパスが.bashrcまたは.zshrcの/ usr/binの前にあることを確認する必要があるだけです。

これが正しい場合は、次のように表示されます。

which easy_install

/ usr/local/binの下など、使用しているpythonインストールと同じパスを共有します。次に、単に実行します:

easy_install pip

そして、使用しているpythonに適したパッケージのインストールを開始します。

7
fivetentaylor

直接質問への回答

site-packagesディレクトリにsitecustomizeというディレクトリを作成できます。説明するように、これをsitecustomizeモジュールに変換します here (Python 2 here )。具体的には:

sitecustomizeという名前のモジュールをインポートしようとします。これにより、任意のサイト固有のカスタマイズを実行できます。これは通常、システム管理者がサイトのパッケージディレクトリに作成します。

sitecustomizeディレクトリに__init__.pyというファイルを作成し、そこに実行する操作を追加します。非常に単純な例は次のとおりです。

import sys
sys.path = ['/your/path/to/pip/install'] + sys.path

あなたの場合、your/path.../usr/local/lib/python2.7/dist-packagesになると思います。より洗練された処理を実行することもできますが、これはsys.pathに大まかに付加され、pythonが開始されるたびに実行されます(たとえば、コマンドラインでインタープリターを開始するか、pythonファイルからのスクリプト)。

警告

私はこれをすることの大いなる擁護者ではありません-それはあなたが望むことをするための少し率直な方法です。しかし、virtualenvを使用することは望ましくなく、変更を「グローバルに」行いたいと具体的に言っていますが、これはあなたが望むことを実行すると思います。

根本的な問題についての考え

@fivetentaylorの answer はここで正しい方向に進んでいると思います。あるインストールからpipを使用しており、別のインストールではpython実行可能ファイルを使用しているようです。パスをいじってこれをマスクすると、非常に混乱しやすくなります。 pipのインストールごとに個別のpythonを確実に用意し、それを使用します。これにより、個別のインストールのディレクトリ構造が個別に保持されます。それ以外の場合は、1つのインストールで別のインストールのディレクトリのパッケージを使用する必要があります。技術的には問題ありませんが、ロジスティックでは混乱しています。

4
J Richard Snape

グローバルに存在するすべてのパッケージを再インストールする必要があるため、virtualenvを使用すると、マシンに不要な変更が発生します。 Ubuntuのパッケージからpipのパッケージにアップグレードしたいだけです。

いいえ、使用できます --system-site-packages

編集

# 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']

ご覧のとおり、このvirtualenvのパスにはシステムパスが含まれています。それが機能しているかどうかを確認するために、システム全体にパッケージをインストールしましたafter 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'>

もちろん、virtualenvの内部にインストールされているものは、システム全体のライブラリよりも優先されます。

あなたのニーズにお答えします。

3
bufh

site.pyドキュメントで説明されているように、sitecustomizeを使用してこれを行います。このファイルは、最初のsys.pathが構成された後にインポートされ、必要に応じて任意の方法でsys.pathを変更するために使用できます。

私はカスタムリリースの場所を含めるためのシステム管理者としてそれを使用しており、非常にうまく機能します。

https://docs.python.org/2/library/site.html

2
matthewatabet

さて、他の人たちが提示した代替案は非常に受け入れられ、さらに良いかもしれません。ただし、sys.path()の方法を使用する場合は、リストのように扱い、挿入メソッドを使用します。

import sys
sys.path.insert(0, "path_to_pip") 
from subprocess import call
call("Sudo pip install requests") 
2
ytpillai

bufh's の回答で問題が解決しますが、Ubuntu提供のバージョンを使用したくないパッケージが他にもあることに気付くでしょう。したがって、virtualenvsを使用してパッケージのバージョンを管理する(システムのバージョンをオーバーライドしようとしない)理由は次のとおりです。

お気づきのとおり、sys.pathの順序は、pythonパッケージが検出される順序を設定します。これは、sys.pathの変更がpythonスクリプトに影響を与えることを意味しますそれらのインポート、両方のスクリプト、およびUbuntuによって提供されるスクリプトを見つけます。pythonスクリプトが使用されている場合、 Ubuntuプログラムでは、Ubuntuプログラムが使用するpythonパッケージのバージョンを変更することで、興味深い方法でUbuntuを「壊す」ことができます(これがdist-packagesが存在する理由です)。

これを回避するために、virtualenvが作成されました。これにより、さまざまなパッケージのセットを効果的に使用できます。 virtualenvsの使用と管理を簡単にするユーティリティがたくさんあります。おそらくあなたにとって最も興味深いものは pipsi です。これはスクリプトごとにvirtualenvを作成し、それをアクティブにする必要を回避します。

1
James Tocknell

物音から、Ubuntuは here に記載されているパッケージパス構成ファイルを使用して、インストールするパッケージをセットアップしています。

site.py を見ると、サイトパッケージディレクトリを解決するときに構成ファイルを呼び出すパス解決の特定の順序があることがわかります。

私はそれが私が見ることができる3つのオプションをあなたに与えると思います:

  1. @bufhの回答に従ってvirtualenv --system-site-packagesを使用します。
  2. pip user installs を使用して、標準サイトパッケージの前のパスに必要なパッケージを設定します。
  3. Sitecustomizeを使用してsys.pathを書き換えます(たとえば、ローカルディレクトリを最初に配置します)。
1
Peter Brittain