【问题标题】:Best practises for imports in Python 3 packages and scriptsPython 3 包和脚本中的导入最佳实践
【发布时间】:2018-10-15 14:08:03
【问题描述】:

考虑这个简单的文件夹结构:

root
  Package1
    x.py
    y.py
  Package2
    z.py
  Examples
    main.py

现在我们的要求是:

  • x.py需要导入y.py
  • z.py需要导入y.py
  • main.py需要导入y.py和z.py

以下是有效的:

x.py

import y

def x():
  y()

y.py

def y():
  pass

z.py

import package1.y as y

def z():
  y.y()

ma​​in.py

import sys
from os import path
sys.path.append(  path.dirname(  path.dirname( path.abspath(__file__) ) ) )

import package1.y as y
import package2.z as z

y.y()
z.z()

问题:

  1. 这是在 Python 3 中设置导入的最佳和推荐方法吗?
  2. 我真的不喜欢在main 中更改sys.path,因为它强烈绑定了关于代码文件内部 包位置的假设。有什么办法解决吗?
  3. 我也真的不喜欢as y 中多余的import package1.y as y 部分。有什么办法解决吗?

【问题讨论】:

  • 只是为了确保我理解,root 不是一个包。您有两个独立的包,分别称为 Package1Package2sys.path 选项不好,因为这意味着我无法克隆此软件包的不同副本以进行开发。我认为最好的选择是为每个包创建setup.py 文件并使其可安装。现在有人可以安装、安装到 virtualenv 中,或者在任何测试之外设置他们自己的路径到他们碰巧使用它们的地方。为只想安装的最终用户提供便利。
  • ...但对于有一点额外知识的开发人员来说也很容易使用它们。
  • x.py 可以做到import .yz.py 是在一个完全独立的包中。它需要完整的Package1.y
  • 是的,root 不是包。问题是在开发过程中源代码在磁盘上的外观如何?
  • 好问题!每个人都有自己的源存储库并且彼此之间没有任何硬编码关系,这是很常见的。用户可以pip install 他们,开发人员可以pip install --editablepip install --develop 他们。即使它们出于其他原因在同一个存储库中,它们仍然是独立的 python 实体。 (当然这都是我的拙见)

标签: python packages python-import


【解决方案1】:

与往常一样,有两个单独的步骤:

  1. 您针对包的abstract 命名空间编写代码,其中包含package1package2(以及sysos) ,但不是“示例”,它不是一个包(因为main.py 不是一个模块)。
  2. 您在任何代码运行之前适当地设置sys.path。如果是您自己的(卸载的)代码,则有 places you can put it,或者您可以编写一个简单的 shell 脚本包装器来为您的 python 进程设置 PYTHONPATH

所以你的问题的答案是

  1. x.py 你写from . import y。 (Python 2 支持这一点,而 3 需要它。)
  2. 如何设置sys.path 取决于您的打包/环境系统。传统方法是为python 进程设置PYTHONPATH 环境变量,但还有其他方法涉及site 模块等。
  3. from package1 import y 是只命名一次的常用方式。

【讨论】:

  • 注意第 2 步:“安装您的软件包”是设置 sys.path 的有效方式 :)
  • @Josh:当然,如果您的环境支持“安装”;很多人使用虚拟环境等等,但我们中的一些人必须将包放在非默认位置并使用外部配置,如Environment Modules。了解任何情况下的基本机制都是有用的。
  • 应该不需要安装包(如果他们愿意,用户可以,但最佳实践不应该要求它)。如果您处于开发模式,这一点尤其重要,并且您可能只想将您的包复制到您自己的版本的私有文件夹中,而不影响系统级包。
  • 在 x.y 中,为什么要写 from . import y 而不仅仅是 import y。前者很冗长,Python 3 实际上并不需要。
  • @ShitalShah:如果xy 在一个包中,那肯定是必需的。如果您在sys.path 上有目录Package1(而不是其父目录),则没有包,但这似乎不是您想要的。
猜你喜欢
  • 2016-10-12
  • 1970-01-01
  • 2013-07-17
  • 2021-03-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多