python 2.7 包中的多个相对导入

Multiple relative imports in python 2.7 packages

我知道有很多关于相关进口的问题。我会记录我尝试了其中的解决方案的程度,但我仍然无法解决我的问题。

我有以下目录结构。这不是我设计的,但我喜欢根据需要修改东西(分叉回购)。

exp
  main_Exp.py
  kaffe
    __init__.py
    tensorflow
      __init__.py
      network_shape.py
  ResNet
    __init__.py    (*)
    ThreeDMM_shape.py

对于运行这个repo中的模型,我要使用

python main_Exp.py input_file.csv

里面 main_Exp.py:

sys.path.append('./kaffe')
sys.path.append('./ResNet')
from ThreeDMM_shape import ResNet_101 as resnet101_shape
from ThreeDMM_expr import ResNet_101 as resnet101_expr

里面 ResNet/ThreeDMM_shape.py:

sys.path.append('/home/usc/Desktop/Research/FG18/ExpNet_Code_Release/kaffe/tensorflow')
from network_shape import Network_Shape

好的,显然我需要更改这个硬编码的绝对路径。我想以正确的方式进行操作,而不是使用我碰巧将这些文件安装到的特定路径。


所以我试试

from ..kaffee.tensorflow import Network_Shape

>>> ValueError: Attempted relative import in non-package

(1) 我在 ResNet 文件夹中添加了 __init__.py 文件(显示为 (*)) (2) 我尝试 运行 将文件作为一个模块:python -m main_Exp input_file.csv (3) 我还尝试将 __init__.py 添加到顶级文件夹 (exp),尽管我认为这样做是无稽之谈。 (4) 鉴于第一次导入是使用附加到 sys.pathkaffe 路径进行的,我尝试将导入更改为 from .tensorflow.network_shape import Network_Shape

所有步骤后出现同样的错误。

所以我不了解有关相对导入的规则以及如何以理智的方式引用文件。我真的很感激能帮助我了解如何执行此操作以及如何总体上考虑此类导入的指示!

exp 确实不是一个包,即使你向它添加一个初始化文件也不会成为一个包,因为这不会神奇地将它添加到路径 python寻找包裹。如果您确实添加了 __init__.py,那么您可以 运行 作为 python -m exp.main_Exp input_file.csv(来自 ../exp)。这将使 python 将 exp 识别为包,将 kaffe/ResNet 识别为子包。您需要将导入更改为 from ResNet.ThreeDMM_shape import ResNet_101 as resnet101_shape

编辑以回应 : 运行 来自使用 m 开关的父目录是 运行 脚本的推荐方式,例如参见 [​​=17=] (这是 python 3 但它应该仍然适用)。如果你想避免它(它会破坏一个硬编码的相对路径)你应该将 exp 添加到 sys 路径(一次可能就足够了)然后将导入更改为绝对路径,如:

# main_Exp.py
sys.path.append(os.path.abspath(os.path.dirname(__file__))) # the exp folder
from ResNet.ThreeDMM_shape import ResNet_101 as resnet101_shape
from ResNet.ThreeDMM_expr import ResNet_101 as resnet101_expr

# ResNet/ThreeDMM_shape.py
from kaffee.tensorflow import Network_Shape