常用的例子如下:
package
----subpack1
----__init__.py
----module11.py
----subpack2
----__init__.py
----module21.py
其中module.py内容如下:
def funA():
print "funcA in module 11"
return
现在在package中写一个测试脚本:
from subpack1.module11 import *
if __name__ == '__main__':
funA()
写完测试没有问题,如果我们在module21..py中应用modle11.py中的函数或方法如何实现呢?
如果在module21..py中内容如下:
from subpack1 import module11
def funB():
module11.funA()
if __name__ == '__main__':
funB()
此时编译会报错,ImportError: No module named subpack1
如果再修改一下, from ..subpack1 import module11
此时还是会报错,ValueError: Attempted relative import in non-package
这个错误原因网上有解释,
包含相对路径import 的python脚本不能直接运行,只能作为module被引用。原因正如手册中描述的,所谓相对路径其实就是相对于当前module的路径,但如果直接执行脚本,这个module的name就是“__main__”, 而不是module原来的name, 这样相对路径也就不是原来的相对路径了,导入就会失败,出现错误“ValueError: Attempted relative import in non-package”
Note that both explicit and implicit relative imports are based on the name of the current module. Since the name of the main module is always"__main__", modules intended for use as the main module of a Python application should always use absolute imports.
但是如何解决这个问题呢,如何从一个模块中引用另一个模块,并且可以做单元测试,我这里提供一种办法,
import os,sys
#os.path.abspath(os.path.join(os.path.dirname('settings.py'),os.path.pardir))
module1 = os.path.abspath(os.path.join(os.getcwd(),os.path.pardir))
sys.path.append(module1)
print sys.path
from subpack1 import module11
def funB():
module11.funA()
if __name__ == '__main__':
funB()
通过将上级目录加入PYTHONPATH中就可以让解释器找到相应的模块。