我有一个像这样的python项目:
repo_dir/
----project_package/
--------__init__.py
--------process.py
--------config.py
----tests/
--------test_process.py
__init__.py
为空
config.py
看起来像这样:
name = 'brian'
USAGE
我通过从python process.py
目录运行project/project/
或绝对指定python文件路径来使用该库。我在Amazon EC2 Linux上运行Python 2.7。
如果process.py
如下所示,一切正常,process.py
打印brian
。
import config
print config.name
当process.py
如下所示时,我收到错误ImportError: No module named project.config
。
import project.config
print config.name
当process.py
如下所示时,我收到错误ImportError: No module named project
。这是有道理的,因为应该预期前一个例子中的相同行为。
from project import config
print config.name
如果我将这些行添加到process.py
以将库根包含在sys.path
中,则上述所有配置都可以正常工作。
import os
import sys
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(__file__), '..')))
MY CONFUSION
许多资源建议设置python库以使用project.module_name
导入模块,但它似乎并不像sys.path
追加是标准的,而且我需要它似乎很奇怪。我可以看到sys.path追加将我的库根添加为sys中的路径,但我认为我的库根中的__init__.py
应该是什么。是什么赋予了?我错过了什么?我知道Python导入会产生很多麻烦,所以我试图尽可能地简化它以包围它。我已经疯了,而且在假期之前是星期五。我很沮丧。请帮忙!!
问题
我应该如何设置我的库?我该如何导入包裹?我应该在哪里有__init__.py
个文件?我是否需要在每个项目中将我的库根附加到sys.path?为什么这么混乱?
答案 0 :(得分:1)
您的项目设置没问题。为了清楚起见,我重命名了这些目录 在这个例子中,但结构与你的相同:
repo_dir/
project_package/
__init__.py
process.py
config.py
# Declare your project in a setup.py file, so that
# it will be installable, both by users and by you.
setup.py
当你有一个想要从另一个模块导入的模块时 同一个项目,最好的方法是使用相对进口。例如:
# In process.py
from .config import name
...
在开发框中处理代码时,请使用Python virtualenv进行工作, 和pip以“可编辑”模式安装项目。
# From the root of your repo:
pip install -e .
通过这种方法,您永远不需要使用sys.path
来解决问题
几乎总是错误的方法。
答案 1 :(得分:1)
我认为问题在于你是如何运行脚本的。如果您希望脚本位于包(内部project
文件夹)中,则应使用python -m project.process
而不是文件名运行它。然后,您可以进行绝对或显式相对导入,以从config
获取process
。
绝对导入为from project import config
或import project.config
。
显式相对导入为from . import config
。
Python 2也允许隐式相对导入,但它们是一个非常糟糕的错误,你永远不应该使用它。使用隐式相对导入,内部包模块可以影响顶级模块。例如,project/json.py
文件将隐藏包中所有其他模块的标准库json
模块。您可以通过将from __future__ import absolute_import
放在文件顶部来告诉Python您要禁止隐式相对导入。这是Python 3中的标准行为。