免责声明:在搜索了大量非常相似的信息后,最终所有信息都解决了一个稍微不同的问题,我想我必须打开一个新问题(尽管我确定某处存在答案 - >所以指出如果你知道的 ;)
问题:我正在使用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。因此,我在那里擦肩而过
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
我还是不知道哪里出错了?
与sys.path
混淆不是一个好主意。
由于您的计划似乎是使用来自foo
的test
和notebooks
(可能只包含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 .
它应该合作
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