如何处理使用绝对导入且在python中具有相同文件夹和文件名的多个项目?

如何处理使用绝对导入且在python中具有相同文件夹和文件名的多个项目?,python,python-import,setuptools,bazel,pythonpath,Python,Python Import,Setuptools,Bazel,Pythonpath,如何导入使用绝对导入且具有相同文件夹和文件名的多个项目 我正在研究ML代码,许多作者编写的代码并不意味着是pip包,文件夹和文件名有很高的重叠,导入是绝对的,假设他们的代码的根是PYTHONPATH的根。设置如下所示: myproject myversion mymodel.py third_party version1 model.py util.py version2 model.py util.py 内容包括

如何导入使用绝对导入且具有相同文件夹和文件名的多个项目

我正在研究ML代码,许多作者编写的代码并不意味着是pip包,文件夹和文件名有很高的重叠,导入是绝对的,假设他们的代码的根是PYTHONPATH的根。设置如下所示:

myproject
  myversion
    mymodel.py
  third_party
    version1
      model.py
      util.py
    version2
      model.py
      util.py
内容包括:

# myproject/third_party/version1/model.py
import util

def process(x):
  return 2*util.preprocess(x)
例如,运行
PYTHONPATH=/path/to/myproject-myversion/mymodel.py

# myproject/myversion/mymodel.py

from third_party.version1.model import process as process1
from third_party.version2.model import process as process2

def myprocess(x):
  return x

def compare(x):
  return process1(x), process2(x), myprocess(x)
但我被困住了,因为每个版本1和版本2都需要不同的路径才能找到自己的util

这里真正的解决方案是什么?我知道,如果版本1和版本2文件(不是我编写的)中使用了相对导入,那么就很容易了。我还知道,如果我只使用这两个选项中的一个,那么只需给出PYTHONPATH=/path/to/myproject:/path/to/myproject/third_party/version1即可,一切都会很好。但我想两者都用。在理想情况下,我不会对version1和version2内部的代码进行太多或根本不做任何更改

我希望我能做的是完全封装version1和version2代码,当它们运行时,它们神奇地知道在哪里查找自己的文件。我尝试使用
setuptools
,但仍然存在路径问题。我怀疑bazel可以用来做这个

p、 使用Python3


p、 我上传了一个

这些实际上是“隐式相对导入”,在Python 3中甚至不起作用。您正在使用Python2.x吗?注意:没有明智的解决方案不涉及更改version1和version2中的源代码以使用正确的命名空间导入语句。这是因为
sys.modules
只是一个dict,您不能将同一个键“util”放在其中两次。感谢info@wim,我正在使用python 3。你知道bazel或其他系统能否解决这个问题吗?看起来版本1和版本2可以“构建”成自包含的,然后使用。我不熟悉bazel。但是这个问题存在于导入系统本身,所以我不知道有什么解决方法-要在同一个运行时中有两个util模块,那么它们必须以某种方式命名。
# myproject/third_party/version1/util.py

def preprocess(x):
  return 1
# myproject/third_party/version2/util.py

def preprocess(x):
  return 0
# myproject/myversion/mymodel.py

from third_party.version1.model import process as process1
from third_party.version2.model import process as process2

def myprocess(x):
  return x

def compare(x):
  return process1(x), process2(x), myprocess(x)