2013-08-30 30 views
9

我有一個完全包含在目錄結構如下python程序:Python:模塊和包裝 - 爲什麼__main__.py之前沒有執行__init__.py文件?

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

我希望能夠打包這和分發,以便其他開發人員可以做pip install -e /path/to/git/clone/of/myprog,然後可以導入MYPROG在他自己的程序中,用它做很酷的事情。

我也想能夠在命令行中運行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

您必須導入除builtins以外的所有內容,所以答案是非常明顯的「是」。 –

回答

9

Do I have to import these functions into __main__ somehow?

是。只有builtins中的項目可以在沒有導入的情況下使用。例如:

from myprog import func1, func2 

應該這樣做。

如果您沒有安裝在普通的Python路徑myprog做,那麼你可以解決它的東西,如:

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去,把-m在命令行上,在這種情況下__main__.py可以關注一下:

from myprog import function_you_referenced_from_init_file 
+0

這看起來不錯,但它不適用於我的機器。我已經嘗試過兩種或三種不同的導入變體,並且我總是會得到「ImportError:No module named myprog」 – jononomo

+0

請參閱我對原始文章的編輯以獲取更多詳細信息。 – jononomo

+0

@JonCrowell:那麼你沒有安裝myprog模塊,所以Python沒有找到它。查看打包和開發:http://guide.python-distribute.org/ http://www.scotttorborg.com/python-packaging/快速入門:將myprog上方的目錄添加到PYTHOPATH中。 –

13

__init__.py只加載當你導入。而是通過執行目錄將目錄視爲腳本

但您仍然可以將該包視爲腳本,而不是目錄。爲了既把該目錄作爲一個包爲主腳本,通過使用-m開關:

python -m myprog 
+0

我試過了,現在得到一個'No module named myprog'。 [這個答案](http://stackoverflow.com/questions/16637428/relative-import-in-python-3-not-working#33195094)似乎表明,將目錄視爲包*和*腳本是不好的實踐。思考? – Jens

+0

答案陳述了個人意見。幾個標準庫模塊,以及像'virtualenv'和'pip'這樣的流行軟件包都可以作爲腳本運行。我個人欣賞並使用這個功能。如果你得到一個* No模塊,名爲Foo *錯誤,你的模塊也不能被導入;你確定它在你的Python路徑上可用嗎? –

2

所以,說完看着對方的反應,而不是被激動,我想:

from __init__ import * 

來自我的__main__.py文件。

我想它不允許你按名稱引用模塊,但對於簡單的情況它似乎工作。

相關問題