2011-02-03 3 views
11

私はPythonでプロジェクトを作成しましたが、私はパッケージがどのようにPythonで動作するのか不思議です。私は私のexample.pyモジュールでmodule.pyを含めて約行くかどうPythonのプロジェクトとパッケージディレクトリのレイアウト

top-level dir 
    \ tests 
    __init__.py 
    \ examples 
    __init__.py 
    example.py 
module.py 

は、ここに私のディレクトリレイアウトです。私はPYTHONPATHを最上位のディレクトリに設定することができますが、それは良い解決策のようには見えません。これはpydevがこの問題を回避する方法ですが、私は環境変数を更新する必要のない解決策を望みます。

私はこのようなのsys.pathを更新するexample.pyの上部に何かを置くことができます:

from os import path 
import sys 

sys.path.append(path.dirname(path.abspath(path.dirname(__file__)))) 

私は、これはどちらかの適切な解決策ではないと思います。

私はPythonパッケージの基本的な部分が欠けているように感じます。私はこれをPython 2.6でテストしています。それ以上の説明が必要な場合は、教えてください。

+0

http://jcalderone.livejournal.com/39794.html –

答えて

8

Pythonパッケージは非常に単純です:パッケージは__init__.pyファイルを持っているのsys.path内のエントリの下の任意のディレクトリです。しかし、モジュールは、import package.moduleまたはfrom package import moduleのような相対インポートによってインポートされた場合にのみ、パッケージ内にあるとみなされます。つまり、は、PYTHONPATHかどうかにかかわらず、インポート可能にするパッケージの上にあるディレクトリを含むsys.pathをに設定する必要があります。

主な問題は、メインモジュール(コマンドラインから直接実行されるモジュール)が、その場所に関係なく常に__main__であることです。したがって、彼らは絶対的なインポートをしなければならず、PYTHONPATHが設定されているか、munge sys.pathそれ自身に依存しています。

あなたのケースでは、正しいパスを設定した後でサンプルを実行する小さなPythonスクリプトをお勧めします。

#!/usr/bin/env python 
import sys 
import os.path 

sys.path.append(os.path.dirname(__file__)) 
example = __import__("examples", globals(), locals(), sys.argv[1]) 

あなたの例では、 "インポートモジュール"を実行できます。

module.pyをパッケージに入れる場合は、sys.pathに "最上位ディレクトリ"のPARENTを追加して、サンプルモジュールでfrom .. import module構文を使用してください。また、ラッパーの最初のパラメーターを__import__に変更し、 "tldname.examples"に置き換えます。ここで、tldnameは最上位ディレクトリーの名前です。

「サンプルランナー」モジュールに依存したくない場合は、各例でsys.path定型文が必要です。または、PYTHONPATH設定が必要です。ごめんなさい。

+0

他のモジュールを使用しないで特別に扱われているメインモジュールは、移植性に優れた方法でこれを釘付けにするヒントでした。現在の主な方法では、ローカルプロジェクトのトップディレクトリを一貫してsys.pathに追加します、それ以外のものはすべて期待どおりに動作します。 –

1
+0

これを試すと、次のエラーが発生します。ValueError:非パッケージでの相対インポートを試みました。私はexamplesディレクトリと親ディレクトリに '__init __。py'を持っています。 – Joe

+0

パッケージで作業していない場合は、はい、PYTHONPATHを設定する必要があります。 – Amber

+0

私はパッケージで作業しています。私は最上位ディレクトリとexamplesディレクトリの両方に '__init __。py'を持っています。 – Joe

関連する問題