Pythonパッケージをローカルディレクトリからインタプリタにインポートします


86

ローカルディレクトリでパッケージを開発/テストしています。インタプリタ(v2.5)にインポートしたいのですが、sys.pathに現在のディレクトリが含まれていません。今、私はを入力しsys.path.insert(0,'.')ます。もっと良い方法はありますか?

また、

from . import mypackage

このエラーで失敗します:

ValueError: Attempted relative import in non-package

その「。」はどこで読みましたか。Pythonモジュールでしたか?
S.Lott 2009

16
@Lott:それは相対インポートパスは、ここで説明しています:docs.python.org/reference/...
projectshave

1
この決定的なガイドをご覧になる
Kevin Zhu

回答:


44

相対インポートは、パッケージの一部としてインポートされたモジュール内からのみ使用できます。スクリプトまたはインタラクティブインタープリターはそうではなかったので、もちろんfrom . import(つまり、「インポート元と同じパッケージからインポート」)は使用しません。動作しません。import mypackageの親ディレクトリmypackageが入っsys.pathていることを確認したら問題ありません(現在のディレクトリをどのようにして私から遠ざけるsys.pathことができたのかわかりません-site.pyに何か奇妙なものがありますか...?)

現在のディレクトリをsys.pathそこに戻すことは、実際、そこに置くよりも良い方法はありません。


Ubuntu8.10用のPython2.5には、インタープリターのsys.pathに現在のディレクトリ(空の文字列)がありません。私は何も変更しなかったので、どういうわけかそのように出荷されました。3.0をインストールしたところ、sys.pathのsys.pathに ''があります。
プロジェクトは

@ projectshave、OK、Ubuntuには間違いなく理由があります!8.04(現在仕事で使用しているもの)では気づいていませんが、十分な注意を払っていなかったのかもしれません。
Alex Martelli

1
私は部分的に間違っています。シェルから呼び出されたPythonの現在のディレクトリは、sys.pathにあります。Emacsから呼び出されたPythonには現在のディレクトリがありません。奇妙な。
プロジェクトは

1
ああ、それなら、Ubuntuとは対照的に理由を持っているのはEmacsです(vimユーザーとして私は本当に知りません;-)。条件付きで「。」を挿入できます。もちろん、sys.pathにない場合は。
Alex Martelli

@Alex Martelli:ありがとうございます!私は、アドオン(Anki用)がスクリプトとして「ローカル」で実行されるときに別のインポートステートメントが必要な理由の解決策を探していました。代わりにlocal_launch()メソッドを追加し、パッケージフォルダーの外部のスクリプトからすべてをインポート/起動すると、それは魅力のように機能しました。
Jon Coombs 2014年

17

sys.pathのドキュメントを参照してください。

http://docs.python.org/library/sys.html#sys.path

引用するには:

スクリプトディレクトリが利用できない場合(たとえば、インタプリタがインタラクティブに呼び出される場合、またはスクリプトが標準入力から読み取られる場合)、path [0]は空の文字列であり、Pythonに現在のディレクトリ内のモジュールを最初に検索するように指示します。

したがって、モジュールを含むディレクトリからpythonインタープリターを起動する場合は、sys.pathを使用する必要はありません。

また、パッケージをインポートするには、次のようにします。

import mypackage

パッケージを含むディレクトリはすでにsys.pathにあるので、正常に機能するはずです。


1
同様のファイル名が作業環境のどこかに存在する場合は失敗します。
JAR.JAR.beans 2016年

@ JAR.JAR.beansは、現在の作業ディレクトリを最初にsys.path配置する必要があるため、作業環境内の他の場所のファイルよりも先にファイルが見つかるはずです。
SpoonMeiser 2016年

3
いい視点ね。つまり、ローカルディレクトリからファイルを実行する場合です。それが他のフォルダである場合、およびsys.pathへの変更が必要な場合、それはsys.path.insert(0, new_path)ではなくを意味しsys.path.append(new_path)ます。
JAR.JAR.beans 2016年

14

変更されていないPythonスクリプトを実行して、特定のローカルディレクトリからライブラリをインポートする場合は、PYTHONPATH環境変数を設定できます(例:bash)。

export PYTHONPATH=/home/user/my_libs
python myscript.py

現在の作業ディレクトリからインポートするだけの場合は、次の.表記を使用します。

export PYTHONPATH=.
python myscript.py

PYTHONPATHのエクスポートには、Pythonの外部(bashなど)でのプログラミングが含まれます。さらに、docs.python.org / 3 / using / cmdline.htmlには、「デフォルトの検索パスはインストールに依存する」と明記されています
iliasiliadis18年

13

複雑にしないでおく:

 try:
     from . import mymodule     # "myapp" case
 except:
     import mymodule            # "__main__" case

7
私はこのソリューションが好きです、それは最も簡単です。唯一の残りの質問は輸入を実装する際のルールはオプションとみなされている「それをする唯一の方法は、」...真剣に宣言するために、約15の方法があるなかった理由であると欠点を持っているすべてがパッケージを整理する
レオGermond

5

それを機能させる簡単な方法は、Pythonの-mフラグを使用して親ディレクトリからスクリプトを実行することpython -m packagename.scriptnameです。明らかに、この状況では__init__.py、ディレクトリをパッケージに変換するためのファイルが必要です。


5

setup.pyがある場合はパッケージ内に、それをインストールすることをお勧めします

pip install -e .

3

使用にsys.pathは、現在のディレクトリがすでに含まれている必要があります。

試してみてください:

import .

または:

from . import sth

ただし、それは良い習慣ではないかもしれないので、なぜ単に使用しないのですか?

import mypackage

5
<import mypackage>の問題は、グローバルpython環境からパッケージをロードし、ローカルフォルダーからパッケージ/ファイルをロードする可能性があることですが、作業環境にある他のランダムなmypackgeをロードすることもできます。
JAR.JAR.beans 2016年

2

パーティーに少し遅れましたが、これが私にとってうまくいったことです:

>>> import sys
>>> sys.path.insert(0, '')

どうやら、空の文字列がある場合、Pythonは現在のディレクトリを検索する必要があることを認識しています。に空の文字列がないため、sys.pathこのエラーが発生しました。


0

私が使用しpathlibたパッケージと@maninthecomputer応答が私のために仕事をしなかったので、私はモジュールをインストールしないようしたいと私のシステムパスに私のモジュールディレクトリを追加します

import sys
from pathlib import Path

cwd = str(Path(__file__).parent)
sys.path.insert(0, cwd)
from my_module import my_function
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.