1

os.chdir()を使用してスクリプトからパッケージディレクトリにアクセスすると、名前空間のインポートが機能しないのはなぜですか?

たとえば、これが問題を示すための私のパッケージ構造です。

testpk/
testpk/bin
testpk/bin/runit.py
testpk/lib
testpk/lib/libcode.py
testpk/lib/__init__.py

これがインポートされたiveを出力する私のlibコードです

print "I've been imported"

runit.pyの内容

#!/usr/bin/python
import  sys, os

if __name__ == "__main__":
    os.chdir('/home/moorepe/src/testpk')   
    print "working path = " , os.getcwd()
    import lib.libcode 

runitを実行すると、次のエラーが発生します。

moorepe@halifax$ bin/runit.py 
Traceback (most recent call last):
  File "bin/runit.py", line 6, in <module>
    import lib.libcode 
ImportError: No module named lib.libcode

ただし、Pythonコマンドラインでこれをテストすると、期待どおりに機能します。

    cd testpk
    python -c "import lib.libcode
    I've been imported

そして、これはbindirから機能します。

cd testpk/bin
python -c "import os; os.chdir('/home/moorepe/src/testpk') ; import lib.libcode"
I've been imported

誰かが何が悪いのか説明できますか?

したがって、これが機能しなかった理由は、PythonがPYTHONPATHに加えて現在のdirをパスとして使用するためです。

したがって、このコードはsys.path.append( "。")を追加することで機能します。これは、現在の作業ディレクトリをパスの追加として強制するためです。

4

4 に答える 4

1

これが私が見つけた別の解決策です:

import sys
import os.path
sys.path.insert(1, os.path.join(os.path.dirname(os.path.realpath(__file__)), 'lib') )

#from pprint import pprint as pp
#pp(sys.path)
import libcode

そうすれば、最上位のライブラリ名がlibではなくのように見えますlibcode

「公式」(Pythonic)の方法

Python モジュールを作成している場合は、公式ドキュメントを参照してください。彼らは、モジュールの組織構造__init__.pyに一致するディレクトリ構造と一緒に 使用することをお勧めします(これは、物事を行うための「Pythonic」の方法のようです)。モジュールのロードパスを理解し、モジュールがロード可能になるように適切に設定する限り、従来の Ruby っぽいまたはJava っぽいディレクトリ構造は問題なく機能します。 lib

于 2014-09-24T18:39:52.617 に答える
1

'.'現在のディレクトリの をsys.path検索フォルダ リストに追加するos.chdir()と、 が有効になり、が機能しimport lib.libcode始めます。

ファイルrunit.py:

#!/usr/bin/python
import  sys, os

if __name__ == "__main__":
    sys.path[0:0] = ['.']  # prefix current directory to list
    os.chdir('/home/moorepe/src/testpk')
    print "working path =", os.getcwd()
    import lib.libcode
于 2012-11-04T17:24:14.820 に答える
0

特定のスクリプトから、スクリプト自体に相対的な sys.path にライブラリを追加する場合は、次のように、スクリプトの場所からライブラリの場所を計算する場所を追加できます。

#!/usr/bin/env python
# testpk/bin/runit.py
import os
import sys
_op = os.path
# if file is referred to by symlink, make __file__ point to it's actual location
__file__ = _op.realpath(__file__)
# add __file__'s directory's parent directory to the path
sys.path.append(_op.abspath(_op.join(_op.dirname(__file__), "..")))
import lib

def main():
    pass

if __name__ == "__main__":
    main()

次に、どこからでも実行可能ファイルを呼び出すことができます。

% pwd
/tmp
% ./testpk/bin/runit.py 
I've been imported

の再割り当てでシンボリックリンクを介してスクリプトを実行することを説明したので__file__、これを行うことさえあります:

% pwd
/tmp
% ln -s ./testpk/bin/runit.py 
% ./runit.py 
I've been imported
于 2012-11-04T16:42:36.577 に答える
0

testpk/lib/ が にあることを確認する必要がありますPYTHONPATH

sys.path.append('/path/to/testpk/lib/') 

あなたのパッケージがあなたのPYTHONPATH.

これを行う「正しい方法」は、testpkパッケージとそのすべてのサブディレクトリを Pythonsite-packagesディレクトリに配置することです。

あなたのsite-packages(あなたのにあるはずのPYTHONPATH)がどこにあるかを見つけるため。

GET_PYTHON_LIB_CMD="from distutils.sysconfig import get_python_lib; print (get_python_lib())"
python -c "$GET_PYTHON_LIB_CMD" 

場所を教えてくれます。

于 2012-11-04T16:14:20.657 に答える