dirFoo1\
Foo1.py
lib\
bar1.py
dirFoo3
Foo.cpp
dirFoo2
Foo2.py
lib\
bar2.py
Foo1代码段
# Foo1.py
import lib.bar1
Class bar1_class:
....
Foo2代码段
# Foo2.py
sys.path.append("../dirFoo1/lib")
sys.path.append("../lib") # tried removing this too
import Foo1
....
文件Foo2.py中的错误消息:
File <path_for_Foo2>
import Foo1 File <path_for_Foo1>
from lib.bar1 import bar1_class
ImportError: No module named bar1
尝试使用dirFoo1\Foo1.py
中dirFoo2\Foo2.py
的库时。 Foo1
和Foo2
都有自己的子目录lib。
使用sys路径设置导入Foo1
中的Foo2
sys.path.append(dirFoo1)
导入错误显示在Foo1
中的代码上导入lib.something_from_bar1
报告错误说something_from_bar1
不存在。
好像它指的是dirFoo2
中的lib。
我在__init__.py
和dirFoo1
下的地方确实有适当的dirFoo2
。
有没有办法从另一个未与__init__.py
链接的文件夹中导入库?
答案 0 :(得分:0)
如果您的dirFooX
个文件夹都位于Python模块搜索路径中,则两个lib
文件夹之间会发生冲突,每个文件夹定义一个不同的lib
文件夹。您的代码中只能访问其中一个。您可以通过几种不同的方式解决冲突。
最简单的方法是重命名一个或两个lib
文件夹,并更新import语句以匹配。对于可在模块名称空间的顶级访问的包,名称lib
不是很具描述性。也许它们应该是Foo1Lib
和Foo2Lib
。
另一种选择是将dirFoo1
和dirFoo2
放入包中,以便lib
包是两个不同命名空间中的子包。这可能是最好的方法,因为它不应该要求sys.path
进行任何混乱以使导入工作。只需确保从顶级文件夹(dirFooX
文件夹上方)运行您的脚本,然后使用-m
标记运行python -m dirFoo2.Foo2
而不是python dirFoo2/Foo2.py
。您是&#39;我需要更新各地的导入,使用绝对名称(from dirFoo1.lib.bar1 import bar_class
)或显式相对名称(from .lib.bar1 import bar_class
)。
我的最终选择可能不适合您的情况,但它会起作用。从Python 3.3开始,你可以拥有&#34; namespace&#34;包,可以从多个文件夹而不是一个文件夹加载模块。如果lib
是命名空间包,它将允许bar1.py
和bar2.py
文件显示为解释器内lib
包的一部分。这主要适用于Django
等大型项目,这些项目可以通过第三方模块添加许多额外功能。使用命名空间包允许将所有这些附加模块放入共享命名空间。如果确实想要,你可以使lib
成为命名空间包(尽管我上面说过,lib
是如此通用,以至于使用它可能是一个坏主意这个名字在顶层)。您需要做的就是删除每个__init__.py
文件夹中的lib
个文件。就像我说的那样,这主要用于大型项目,其中许多应该属于单个包的模块由不同的作者编写和分发。除非您的两个lib
文件夹密切相关,否则它可能不适合您的情况。