2014-02-11 70 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