787

相対パスを指定して Python モジュールをインポートするにはどうすればよいですか?

たとえば、 とが含まdirFooFoo.pyている場合、 にインポートするにはどうすればよいですか?dirBardirBarBar.pyBar.pyFoo.py

視覚的な表現は次のとおりです。

dirFoo\
    Foo.py
    dirBar\
        Bar.py

Fooを含めたいと考えてBarいますが、フォルダ階層を再構築することはできません。

4

22 に答える 22

348

両方のディレクトリが実際の Python パッケージである (内部にファイルがある) と仮定すると__init__.py、スクリプトの場所に相対的なモジュールを含めるための安全な解決策は次のとおりです。

スクリプトに一連のモジュールを含める必要があるため、これを行いたいと思います。私はこれをいくつかの製品の本番環境で使用しており、次のような多くの特別なシナリオで機能します。別のディレクトリから呼び出されたスクリプト、または新しいインタープリターを開く代わりに python execute で実行されたスクリプト。

 import os, sys, inspect
 # realpath() will make your script run, even if you symlink it :)
 cmd_folder = os.path.realpath(os.path.abspath(os.path.split(inspect.getfile( inspect.currentframe() ))[0]))
 if cmd_folder not in sys.path:
     sys.path.insert(0, cmd_folder)

 # Use this if you want to include modules from a subfolder
 cmd_subfolder = os.path.realpath(os.path.abspath(os.path.join(os.path.split(inspect.getfile( inspect.currentframe() ))[0],"subfolder")))
 if cmd_subfolder not in sys.path:
     sys.path.insert(0, cmd_subfolder)

 # Info:
 # cmd_folder = os.path.dirname(os.path.abspath(__file__)) # DO NOT USE __file__ !!!
 # __file__ fails if the script is called in different ways on Windows.
 # __file__ fails if someone does os.chdir() before.
 # sys.argv[0] also fails, because it doesn't not always contains the path.

おまけとして、このアプローチでは、システムにインストールされているモジュールではなく、Python にモジュールを使用させることができます。

警告!現在のモジュールがファイル内にあるときに何が起こっているのか、私にはよくわかりませんegg。それも多分失敗。

于 2011-05-23T14:00:43.530 に答える
331

dirBar に__init__.pyファイルがあることを確認してください。これにより、ディレクトリが Python パッケージになります。

于 2008-11-10T21:33:33.887 に答える
264

サブディレクトリを Python パスに追加して、通常のスクリプトとしてインポートすることもできます。

import sys
sys.path.insert(0, <path to dirFoo>)
import Bar
于 2008-11-10T22:04:27.223 に答える
117
import os
import sys
lib_path = os.path.abspath(os.path.join(__file__, '..', '..', '..', 'lib'))
sys.path.append(lib_path)

import mymodule
于 2010-11-26T10:21:28.800 に答える
109

別のフォルダから.pyファイルをインポートする簡単なことをするだけです。

次のようなディレクトリがあるとします。

lib/abc.py

次に、名前の付いたlibフォルダーに空のファイルを保持します

__init__.py

そして、

from lib.abc import <Your Module name>

__init__.pyインポートモジュールの階層のすべてのフォルダーにファイルを保持します。

于 2010-12-09T10:40:09.677 に答える
77

このようにプロジェクトを構成する場合:

src\
  __init__.py
  main.py
  dirFoo\
    __init__.py
    Foo.py
  dirBar\
    __init__.py
    Bar.py

次に、Foo.py から次のことができるはずです。

import dirFoo.Foo

または:

from dirFoo.Foo import FooObject

トムのコメントによると、これには、または検索パスsrcを介してフォルダーにアクセスできる必要があります。site_packagesまた、彼が言及しているように__init__.py、そのパッケージ/ディレクトリにモジュールを最初にインポートすると、暗黙的にインポートされます。通常__init__.pyは単なる空のファイルです。

于 2008-11-10T21:46:04.953 に答える
45

最も簡単な方法は、sys.path.append() を使用することです。

しかし、impモジュールにも興味があるかもしれません。内部インポート機能へのアクセスを提供します。

# mod_name is the filename without the .py/.pyc extention
py_mod = imp.load_source(mod_name,filename_path) # Loads .py file
py_mod = imp.load_compiled(mod_name,filename_path) # Loads .pyc file 

これは、モジュールの名前がわからない場合にモジュールを動的にロードするために使用できます。

私は過去にこれを使用して、ユーザーがアプリケーション固有の機能を備えたスクリプトを記述し、そのスクリプトを特定のディレクトリにドロップするアプリケーションへのプラグイン タイプ インターフェイスを作成しました。

また、次の関数が役立つ場合があります。

imp.find_module(name[, path])
imp.load_module(name, file, pathname, description)
于 2008-11-12T01:56:51.203 に答える
43

これは関連する PEP です。

http://www.python.org/dev/peps/pep-0328/

特に、dirFoo が dirBar から上のディレクトリであると仮定すると...

dirFoo\Foo.py で:

from ..dirBar import Bar
于 2008-11-10T22:22:47.093 に答える
23

スクリプトを変更しない最も簡単な方法は、PYTHONPATH 環境変数を設定することです。sys.path は次の場所から初期化されるため:

  1. 入力スクリプトを含むディレクトリ (または現在のディレクトリ)。
  2. PYTHONPATH (シェル変数 PATH と同じ構文のディレクトリ名のリスト)。
  3. インストールに依存するデフォルト。

とにかく走れ:

export PYTHONPATH=/absolute/path/to/your/module

以下に示すように、sys.path には上記のパスが含まれます。

print sys.path

['', '/absolute/path/to/your/module', '/usr/lib/python2.7', '/usr/lib/python2.7/plat-linux2', '/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/lib/python2.7/dist-packages', '/usr/lib/python2.7/dist-packages/PIL', '/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/ubuntu-sso-client', '/usr/lib/python2.7/dist-packages/ubuntuone-client', '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', '/usr/lib/python2.7/dist-packages/ubuntuone-couch', '/usr/lib/python2.7/dist-packages/ubuntuone-installer', '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol']
于 2013-02-10T23:21:51.977 に答える
13

私の意見では、最良の選択は__ init __.pyをフォルダーに入れて、ファイルを呼び出すことです

from dirBar.Bar import *

既存の python パッケージと同じファイル名を使用すると何か問題が発生する可能性があるため、sys.path.append() の使用はお勧めしません。私はそれをテストしていませんが、それはあいまいです。

于 2010-09-15T05:02:52.807 に答える
12

Linuxユーザーのための手っ取り早い方法

ただいじくり回していて、デプロイメントの問題を気にしない場合は、シンボリックリンクを使用して(ファイルシステムがそれをサポートしていると仮定して)、モジュールまたはパッケージを要求元のモジュールのフォルダーに直接表示できます。

ln -s (path)/module_name.py

また

ln -s (path)/package_name

__init__.py注:「モジュール」は拡張子が.pyのファイルであり、「パッケージ」はファイル(空のファイルの場合もあります)を含むフォルダーです。使用法の観点から、モジュールとパッケージは同一です。どちらも、importコマンドを介して要求されたとおりに、含まれている「定義とステートメント」を公開します。

参照:http ://docs.python.org/2/tutorial/modules.html

于 2012-12-20T01:07:43.913 に答える
11
from .dirBar import Bar

それ以外の:

from dirBar import Bar

別の dirBar がインストールされていて、foo.py リーダーを混乱させる可能性がある場合に備えて。

于 2011-08-31T20:02:15.783 に答える
6

__init__.pyファイルを追加します。

dirFoo\
    Foo.py
    dirBar\
        __init__.py
        Bar.py

次に、このコードを Foo.py の先頭に追加します。

import sys
sys.path.append('dirBar')
import Bar
于 2010-02-28T20:34:59.760 に答える
4

あなたが言及したように、通常、メイン スクリプトが実行されている場所に関連するモジュールを含むフォルダーにアクセスしたいので、それらをインポートするだけです。

解決:

スクリプトD:/Books/MyBooks.pyといくつかのモジュール (oldies.py など) があります。サブディレクトリからインポートする必要がありますD:/Books/includes:

import sys,site
site.addsitedir(sys.path[0] + '\\includes')
print (sys.path)  # Just verify it is there
import oldies

print('done')に aを配置してoldies.py、すべてが正常であることを確認します。sys.pathプログラムの起動時に初期化される Python 定義により、このリストの最初の項目 はpath[0]、Python インタープリターを呼び出すために使用されたスクリプトを含むディレクトリであるため、この方法は常に機能します。

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

于 2015-04-01T22:29:39.357 に答える
4

相対 sys.path の例:

# /lib/my_module.py
# /src/test.py


if __name__ == '__main__' and __package__ is None:
    sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '../lib')))
import my_module

この回答に基づいています。

于 2014-07-29T07:27:39.437 に答える
-15

慎重すぎると言われますが、ファイルがすべてのコンピューターで常に同じ場所にあると想定するのは安全ではないため、私は自分のファイルをよりポータブルにしたいと考えています。個人的には、コードで最初にファイル パスを検索します。私はLinuxを使用しているので、私の場合は次のようになります。

import os, sys
from subprocess import Popen, PIPE
try:
    path = Popen("find / -name 'file' -type f", shell=True, stdout=PIPE).stdout.read().splitlines()[0]
    if not sys.path.__contains__(path):
        sys.path.append(path)
except IndexError:
    raise RuntimeError("You must have FILE to run this program!")

もちろん、これらを一緒にパッケージ化する予定がない限り. しかし、その場合は、とにかく 2 つの個別のファイルは必要ありません。

于 2011-09-22T19:33:39.083 に答える