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
中的 foo
和 test
(可能只包含 Jupyter 笔记本),最干净的解决方案是安装 foo
和 test
作为包。
从顶级目录中删除 __init__.py
和 notebooks
,因为您不想导入它们。然后将 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 .
免责声明: 在搜索了大量非常相似的提要之后,最终都解决了一个稍微不同的问题我想我必须打开一个新问题(尽管我我确定某处有答案 --> 如果您知道,请指出 ;)
问题:我正在使用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
中的 foo
和 test
(可能只包含 Jupyter 笔记本),最干净的解决方案是安装 foo
和 test
作为包。
从顶级目录中删除 __init__.py
和 notebooks
,因为您不想导入它们。然后将 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 .