Python 从兄弟目录导入

Python import from sibling directories

免责声明: 在搜索了大量非常相似的提要之后,最终都解决了一个稍微不同的问题我想我必须打开一个新问题(尽管我我确定某处有答案 --> 如果您知道,请指出 ;)

问题:我正在使用Python 2,正在用这棵树构建一个项目:

project
├── __init__.py
├── foo  
│   └── __init__.py
│   └── bar   
│       └── __init__.py
├── notebooks   
│   └── __init__.py
│   └── skript.py
└── test
    └── __init__.py
    └── foo   
        └── __init__.py
        └── bar   
            └── __init__.py
            └── file.py

现在我想从 project/notebooks/skript.py 中加载 test.foo.bar。因此,我在那个 skript

import sys
sys.path.append('../')

如果我那么运行

import test.foo.bar  # or: import test.foo

python告诉我

ImportError: No module named foo.bar

(或分别为 ImportError: No module named foo)。有趣的是,import test 不会抛出错误,但如果我随后执行 test.foo,它会抛出 AttributeError: 'module' object has no attribute 'foo'

所以我想知道,这里出了什么问题以及如何解决?


编辑

此外,我尝试将其添加到 skript.py

import sys
import os
MYDIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(MYDIR,'../test'))
sys.path.append(os.path.join(MYDIR,'../test/foo'))
sys.path.append(os.path.join(MYDIR,'../test/foo/bar')) #I am not sure this is entirely needed

如下所述。尽管如此,

import test.foo.bar.file

或 从 test.foo.bar 导入文件 只是屈服

ImportError: No module named foo.bar

也一样
sys.path.append('../test/foo/bar')
import test.foo.bar.file

我还是不知道出了什么问题?

它应该适用于

from test import foo

但是你必须在你的项目目录中添加一个__init__.py

对于 Python 3 它将是:

from .test import foo

如果您使用文件夹名称前面的点,python 会在您正在处理的文件所在的同一目录中搜索文件。

抱歉我的英语不好。

您使用的是 IDE 吗?如果是这样,将项目属性内的 Python 解释器的路径添加到所有主要包(foo、test、notebooks)。否则尝试像这样显式地将 bar 包添加到 sys 路径

import sys
import os
MYDIR = os.path.dirname(os.path.abspath(__file__))
sys.path.append(os.path.join(MYDIR,'test'))
sys.path.append(os.path.join(MYDIR,'test/foo'))
sys.path.append(os.path.join(MYDIR,'test/foo/bar')) #I am not sure this is entirely needed

乱用 sys.path 很少是个好主意。

由于您的计划似乎是同时使用 notebooks 中的 footest(可能只包含 Jupyter 笔记本),最干净的解决方案是安装 footest 作为包。

从顶级目录中删除 __init__.pynotebooks,因为您不想导入它们。然后将 setup.py 添加到您的顶级目录。由于您的测试特定于 foo,您应该将它们重命名为 foo_test 或将它们移至 foo 本身。

最小的 setup.py 看起来像这样

from setuptools import setup

setup(name='foo',
      version='0.1',
      description='descroption of fo',
      author='you',
      author_email='your@mail',
      packages=['foo','test_foo])

然后你可以简单地 pip install -e . 在你的顶级目录中,它就会被安装到你当前的 virtualenv 中。如果你没有使用 virtualenvs,你应该 pip install --user -e .