导入问题,维护2个不同的python文件夹

时间:2017-03-07 01:16:53

标签: python directory

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.pydirFoo2\Foo2.py的库时。 Foo1Foo2都有自己的子目录lib。

使用sys路径设置导入Foo1中的Foo2

  

sys.path.append(dirFoo1)

导入错误显示在Foo1

中的代码上
  

导入lib.something_from_bar1

报告错误说something_from_bar1不存在。 好像它指的是dirFoo2中的lib。

我在__init__.pydirFoo1下的地方确实有适当的dirFoo2。 有没有办法从另一个未与__init__.py链接的文件夹中导入库?

1 个答案:

答案 0 :(得分:0)

如果您的dirFooX个文件夹都位于Python模块搜索路径中,则两个lib文件夹之间会发生冲突,每个文件夹定义一个不同的lib文件夹。您的代码中只能访问其中一个。您可以通过几种不同的方式解决冲突。

最简单的方法是重命名一个或两个lib文件夹,并更新import语句以匹配。对于可在模块名称空间的顶级访问的包,名称lib不是很具描述性。也许它们应该是Foo1LibFoo2Lib

另一种选择是将dirFoo1dirFoo2放入包中,以便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.pybar2.py文件显示为解释器内lib包的一部分。这主要适用于Django等大型项目,这些项目可以通过第三方模块添加许多额外功能。使用命名空间包允许将所有这些附加模块放入共享命名空间。如果确实想要,你可以使lib成为命名空间包(尽管我上面说过,lib是如此通用,以至于使用它可能是一个坏主意这个名字在顶层)。您需要做的就是删除每个__init__.py文件夹中的lib个文件。就像我说的那样,这主要用于大型项目,其中许多应该属于单个包的模块由不同的作者编写和分发。除非您的两个lib文件夹密切相关,否则它可能不适合您的情况。