python库如何处理内部导入?

时间:2018-12-20 06:54:36

标签: python python-2.7

考虑以下目录

myProject
    myCode.py
    __init__.py
myProject2
    __init__.py
    myProject2Inner
         myCode.py
         __init__.py

myLibrary
    __init__.py
    myPackage1
        __init__.py
        myPackage1Code.py
    myPackage2
        __init__.py
        myPackage2Code.py

如果myCode.py依赖于myPackage1Code.py,而myPackage1Code.py依赖于myPackage2Code.py

我目前正在执行以下操作

sys.path.append(os.path.abspath('../myLibrary/myPackage2/'))
import myPackage2Code
myPackage1Code.py中按

可使代码成功运行。但这显然很糟糕,因为库导入路径完全取决于使用它的人员。例如,如果myProject2Inner需要myPackage1,则上面的代码将无法工作。

我必须做

sys.path.append(os.path.abspath('../../myLibrary/myPackage2/'))
import myPackage2Code

我认为我在这里做错了什么,有人可以向我指出如何在自包含库中处理导入路径的方向吗?

1 个答案:

答案 0 :(得分:0)

在您的情况下,myLibrarymyPackage1myPackage2是软件包。要从其他软件包中导入模块(或软件包),必须使用绝对路径或相对路径:

# in myPackage1Code.py
# absolute import
from myLibrary.myPackage2 import myPackage2Code
# relative import
from ..myPackage2 import myPackage2Code

这将唯一地标识您实际需要的模块,并告诉Python在哪里找到它。请注意,...不是文件系统操作:它们还与动态组成的名称空间包一起工作。

如果要执行包中包含的脚本,请将该脚本作为包的一部分执行:

python2 -m myLibrary.myPackage1.myPackage1Code

Python2还具有隐式相对导入:

# in myLibrary/__init__.py
from myPackage2 import myPackage2Code

通常不建议使用此格式,因为如果存在全局myPackage2,则会破坏该格式。


请注意,要使程序包正常工作,必须照原样使用它们!如果您直接访问软件包的一部分

 # directly run code module of a package 
 python2 myLibrary/myPackage1/myPackage1Code.py
 # directly import module of a package
 sys.path.append(os.path.abspath('../../myLibrary/myPackage2/'))
 import myPackage2Code

然后Python不知道myPackage2Code属于myLibrary.myPackage2。 这有两个明显的效果:

  • myPackage2Code不能使用相对导入。 Python将其视为顶级模块,因此导入不会在包层次结构中“上升”。
  • 如果另一个模块以完整路径导入它,则会创建两个单独的模块myPackage2CodemyLibrary.myPackage2.myPackage2Code。由于这些对象包含单独的对象,因此它们例如对isinstance子句的except检查失败。