在Pythonic库设计中导入正确的包?
我有一个python项目,其结构如下:在Pythonic库设计中导入正确的包?,python,python-2.7,python-import,Python,Python 2.7,Python Import,我有一个python项目,其结构如下: repo_dir/ ----project_package/ --------__init__.py --------process.py --------config.py ----tests/ --------test_process.py name = 'brian' \uuuu init\uuuu.py为空 config.py如下所示: repo_dir/ ----project_package/ --------__init__.py ---
repo_dir/
----project_package/
--------__init__.py
--------process.py
--------config.py
----tests/
--------test_process.py
name = 'brian'
\uuuu init\uuuu.py
为空
config.py
如下所示:
repo_dir/
----project_package/
--------__init__.py
--------process.py
--------config.py
----tests/
--------test_process.py
name = 'brian'
用法
我通过从project/project/
目录运行python process.py
或指定python文件路径来使用该库。我正在AmazonEC2Linux上运行Python 2.7
当process.py
如下所示时,一切正常,process.py
打印brian
import config
print config.name
当process.py
如下所示时,我得到错误ImportError:没有名为project.config的模块
import project.config
print config.name
当process.py
如下所示时,我得到错误ImportError:没有名为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__), '..')))
我的困惑
许多参考资料建议使用project.module\u name
设置python库来导入模块,但它看起来不像sys.path
追加是标准的,而且我需要它似乎很奇怪。我可以看到sys.path append将我的库根添加为sys中的一个路径,但我认为这就是我的库根中的\uuuu init\uuuuuu.py
应该做的。有什么好处?我错过了什么?我知道Python导入会带来很多麻烦,所以我已经尽可能地简化了它,以使我的头脑更加清醒。我快疯了,现在是假期前的星期五。我很沮丧。请帮忙
问题
我应该如何设置我的库?我应该如何导入软件包?我应该在哪里拥有\uuuu init\uuuu.py
文件?是否需要在每个项目中将我的库根附加到sys.path?为什么这么混乱?您的项目设置还可以。为了清晰起见,我重新命名了目录
在本例中,结构与您的相同:
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在“可编辑”模式下安装项目
使用这种方法,您将永远不需要到处乱搞sys.path
——这
几乎总是错误的方法。您的项目设置是正确的。为了清晰起见,我重新命名了目录
在本例中,结构与您的相同:
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在“可编辑”模式下安装项目
使用这种方法,您将永远不需要到处乱搞sys.path
——这
几乎总是错误的方法。我认为问题在于如何运行脚本。如果希望脚本位于包(内部项目
文件夹)中,则应使用python-m project.process
运行脚本,而不是按文件名运行脚本。然后,您可以进行绝对或显式相对导入,以从过程中获取config
绝对导入将是来自项目导入配置的或导入项目.config
import project.config
print config.name
显式相对导入将是来自的。导入配置
import project.config
print config.name
Python2还允许隐式相对导入,但它们是一个非常糟糕的错误特性,您永远不应该使用它。通过隐式相对导入,内部包模块可以隐藏顶级模块。例如,一个project/json.py
文件将对包中的所有其他模块隐藏标准库的json
模块。您可以告诉Python您希望禁止隐式相对导入,方法是将来自_ufuture\u uu import absolute\u import的放在文件顶部。这是Python 3中的标准行为。我认为问题在于如何运行脚本。如果希望脚本位于包(内部项目
文件夹)中,则应使用python-m project.process
运行脚本,而不是按文件名运行脚本。然后,您可以进行绝对或显式相对导入,以从过程中获取config
绝对导入将是来自项目导入配置的或导入项目.config
import project.config
print config.name
显式相对导入将是来自的。导入配置
import project.config
print config.name
Python2还允许隐式相对导入,但它们是一个非常糟糕的错误特性,您永远不应该使用它。通过隐式相对导入,内部包模块可以隐藏顶级模块。例如,一个project/json.py
文件将对包中的所有其他模块隐藏标准库的json
模块。您可以告诉Python您希望禁止隐式相对导入,方法是将来自_ufuture\u uu import absolute\u import的放在文件顶部。这是Python 3中的标准行为。我是否将其视为可安装的Python应用程序而过度复杂化了?它是我们公司的内部应用程序,不会分发给很多用户,甚至是内部用户。您认为始终将相对较大的python项目视为可安装的软件包是一种好的做法吗?@T.BrianJones使用适当的目录结构和setup.py文件,以标准方式设计您的软件包。除了一些前期学习(一次性成本),每个项目创建文件和声明项目的依赖项所需的时间不超过几分钟。让项目可以通过pip安装有很多好处:您可以与同事甚至全世界共享代码;您可以更好地调试奇怪的场景;你有一个正式的