在Pythonic Library Design中导入正确的包?

时间:2018-05-26 00:16:33

标签: python python-2.7 python-import

我有一个像这样的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?为什么这么混乱?

2 个答案:

答案 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 configimport project.config

显式相对导入为from . import config

Python 2也允许隐式相对导入,但它们是一个非常糟糕的错误,你永远不应该使用它。使用隐式相对导入,内部包模块可以影响顶级模块。例如,project/json.py文件将隐藏包中所有其他模块的标准库json模块。您可以通过将from __future__ import absolute_import放在文件顶部来告诉Python您要禁止隐式相对导入。这是Python 3中的标准行为。