考虑以下目录
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
我认为我在这里做错了什么,有人可以向我指出如何在自包含库中处理导入路径的方向吗?
答案 0 :(得分:0)
在您的情况下,myLibrary
,myPackage1
和myPackage2
是软件包。要从其他软件包中导入模块(或软件包),必须使用绝对路径或相对路径:
# 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将其视为顶级模块,因此导入不会在包层次结构中“上升”。myPackage2Code
和myLibrary.myPackage2.myPackage2Code
。由于这些对象包含单独的对象,因此它们例如对isinstance
子句的except
检查失败。