2013-08-30 10 views
9

私は完全に次のような構造を持つディレクトリに含まれるPythonプログラムがあります。他の開発者がpip install -e /path/to/git/clone/of/myprogを行うことができ、その後、MYPROGをインポートできるように、私はこれをパッケージ化し、それを配布できるようにしたいと思いますPython:モジュールとパッケージング - なぜ__init__.pyファイルが__main__.pyより先に実行されないのですか?

myprog/ 
├── __init__.py 
├── __main__.py 
├── moduleone.py 
└── moduletwo.py 

を彼自身のプログラムでは、それをクールなものをする。

また、私は次のようにコマンドラインでMYPROGを実行できるようにしたい:私はこれを行うと

PROMPT> python myprog 

は、私はPythonはそれがない__main__.pyモジュールを実行することを期待。しかし、このモジュールは、__init__.pyで宣言され、プログラムがコマンドラインで実行されているときと別のプログラムによってインポートされたときの両方で利用可能でなければならない関数を参照します。しかし、私は次のエラーを取得しています:

NameError: name 'function_you_referenced_from_init_file' is not defined 

私は何とか__main__.pyにこれらの関数をインポートする必要がありますか?

次のように私は簡単な例を試してみました:

PROMPT> cat myprog/__init__.py 
def init_myprog(): 
    print 'running __init__.init_myprog()' 

PROMPT> cat myprog/__main__.py 
import myprog 
print 'hi from __main__.py' 
myprog.init_myprog() 

PROMPT> ls -l myprog 
total 16 
-rw-r--r-- 1 iit 63B Aug 30 11:40 __init__.py 
-rw-r--r-- 1 iit 64B Aug 30 12:11 __main__.py 

PROMPT> python myprog 
Traceback (most recent call last): 
    File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 162, in _run_module_as_main 
    "__main__", fname, loader, pkg_name) 
    File "/usr/local/Cellar/python/2.7.5/Frameworks/Python.framework/Versions/2.7/lib/python2.7/runpy.py", line 72, in _run_code 
    exec code in run_globals 
    File "/Users/jon/dev/myprog/__main__.py", line 1, in <module> 
    import myprog 
ImportError: No module named myprog 
+2

質問を閉じることに投票している人は誰でも - それがばかばかしくてシンプルなら、数秒で私に説明できるかもしれませんか?私はこのリンクhttp://stackoverflow.com/questions/3411293/using-modules-own-objects-in-main-pyから学ぶことを試みたが、まだ問題を抱えている。 – jononomo

+0

組み込み関数を除くすべてをインポートする必要があるので、答えはかなり明白な "はい"です。 –

答えて

9

Do I have to import these functions into __main__ somehow?

はい。 builtinsの商品のみがインポートされます。次のようなものがあります。

from myprog import func1, func2 

トリックを行う必要があります。

あなたはmyprogは、通常のPythonのパスにインストールされていない場合は、あなたのようなもので、それを回避することができます、率直に言って、恐ろしいです

import sys 
import os 
path = os.path.dirname(sys.modules[__name__].__file__) 
path = os.path.join(path, '..') 
sys.path.insert(0, path) 
from myprog import function_you_referenced_from_init_file 

私はMartijnPieters suggestionと一緒に行くことをお勧めしている場合__main__.pyは次のように見ることができ、コマンドラインで-mを置く:あなたはパッケージをインポートしているとき

from myprog import function_you_referenced_from_init_file 
+0

これは素晴らしいですが、私のマシンでは動作しません。私は2つまたは3つの異なるバリエーションのインポートを試しましたが、私はいつも "ImportError:myprogというモジュールはありません" – jononomo

+0

詳細については、オリジナルの記事を編集してください。 – jononomo

+0

@JonCrowell:次に、myprogモジュールをインストールしていないので、Pythonはそれを見つけられません。パッケージングと開発を見てください:http://guide.python-distribute.org/ http://www.scotttorborg.com/python-packaging/クイックハック:myprogの上のディレクトリをPYTHOPATHに追加します。 –

13

__init__.pyのみがロードされます。代わりにディレクトリを実行して、スクリプトとしてディレクトリを扱います。

ただし、パッケージをディレクトリではなくスクリプトとして扱うことはできます。だから

python -m myprog 
+0

私はこれを試して、今度は 'myprogという名前のモジュールはありません。 [この回答](http://stackoverflow.com/questions/16637428/relative-import-in-python-3-not-working#33195094)は、ディレクトリをパッケージ*および*スクリプトとして扱うことが悪いことを示しているようです練習。思考? – Jens

+0

答えは個人的意見を述べています。いくつかの標準ライブラリモジュールと、 'virtualenv'や' pip'などの人気のあるパッケージは、スクリプトとして実行されます。私は個人的に感謝し、この機能を使用します。 * Foo *という名前のモジュールがない場合は、モジュールをインポートすることもできません。あなたのPythonパス上で利用可能であることは確かですか? –

2

他の回答を見たと感激していない、私が試した:両方に-mスイッチを使用することにより、メインスクリプトとしてパッケージとしてディレクトリを扱う

from __init__ import * 

から私の__main__.pyファイル。

あなたは名前でモジュールを参照することはできませんが、単純なケースでは動作するようです。

関連する問題