2014-02-11 115 views
2

我將重新整理我的python代碼的大塊作爲一個包。我想這個軟件包會被保存在主代碼所在的同一目錄中。所以整個結構如下所示:導入本地軟件包的麻煩

project directory 
\-mymod 
    \-__init__.py # totaly empty 
    \-xsum.py  # with xsum function 
\-main.py  # main program 

,因爲它只是一個例子

#xsum.py 
def xsum(a,b): 
    "just xsum" 
    return a+b 

而main.py裏面:

#main.py 
import mymod 
print mymod.xsum.xsum(2,3) 

的Python會返回一個錯誤:

Traceback (most recent call last): 
    File "main.py", line 3, in <module> 
    print mymod.xsum.xsum(2,3) 
AttributeError: 'module' object has no attribute 'xsum' 

我試着添加p roject目錄和/或項目目錄/ mymod到sys.path,但它沒有幫助。

+3

'import mymod.xsum'而不是'import mymod' in main.py.或者____init____.py中的'from mymod import xsum',然後您可以在main.py中導入mymod。 – michaelmeyer

+0

@doukremt你是對的,它的工作原理。但這很奇怪。文檔中沒有任何東西。爲什麼我應該直接在'__init __。py'中導入模塊? – rth

+1

我想這是爲了防止名稱衝突。例如,你可以在'__init __。py'中有一個'xsum'函數,然後,如何判斷名稱mymodule.xsum是否指向這個函數,或者是指向文件'xsum.py'?需要記住的是,當你鍵入'import mymodule'時,Python真正導入的是'mymodule/__ init __。py'中定義的名稱集合。因此,爲了保持事物的明確性,將所有模塊文件導入模塊本身的'__init __。py'文件是很方便的。這樣,'import mymod'或'import mymod.xsum'仍然有效。 – michaelmeyer

回答

2

感謝@doukremt(見上述討論)我發現很簡單的解決辦法:在 插入__init__.py代碼

import sys,os 
for filename in os.listdir(os.path.dirname(__file__)): 
     if filename[-3:] != ".py" or filename == "__init__.py" : continue 
     exec "from "+filename[:-3]+" import *" 

它允許導入當前包的包名稱空間從所有PY文件的所有名稱。所以使用非常簡單:

import mymod 
mymod.xsum(2,3) 

,如果你想在一個不同的命名空間獨立的模塊名稱中使用下面的代碼在__init__.py: 進口SYS,OS

for filename in os.listdir(os.path.dirname(__file__)): 
     if filename[-3:] != ".py" or filename == "__init__.py" : continue 
     exec "import "+filename[:-3] 

在這種情況下,你應該指定子模塊:

import mymod 
mymod.xsum.xsum(2,3) 

最後,如果你想在你的目錄導入只是幾個文件,做一個清單,並將其導入:

import sys,os 
__all__=["a","b","c","xsum"] 
for filename in __all__: 
     exec "import "+filename