Python 3包和脚本导入的最佳实践

3
考虑这个简单的文件夹结构:
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()

main.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. 我也非常不喜欢import package1.y as y中多余的as y部分。有没有办法解决这个问题?

只是为了确保我理解,root 不是一个包。你有两个独立的包叫做 Package1Package2sys.path 选项不好,因为这意味着我不能克隆不同的副本来进行开发。我认为最好的选择是为每个包创建 setup.py 文件并使它们可安装。现在,某人可以安装、安装到虚拟环境中,或者在任何测试之外设置自己的路径,以便无论他们在哪里使用它们都能方便地安装。让终端用户轻松安装。 - tdelaney
...而且对于那些具备一些额外知识的开发人员来说,它们也很容易使用。 - tdelaney
x.py 可以使用 import .y,但 z.py 在一个完全不同的包中。它需要完整的 Package1.y - tdelaney
是的,根目录不是包。问题是在开发过程中源代码在磁盘上应该如何呈现? - Shital Shah
好问题!每个项目通常都有自己的源代码库,彼此之间没有硬编码关系。用户可以使用 pip install 安装它们,而开发人员则可以使用 pip install --editablepip install --develop 安装它们。即使它们在同一个代码库中,它们仍然是独立的 Python 实体。(当然,这只是我的个人意见) - tdelaney
1个回答

1

和往常一样,分为两个步骤:

  1. 您针对包的抽象命名空间编写代码,其中包括package1package2(以及sysos等等),但不包括“Examples”,因为main.py不是模块。
  2. 在您的任何代码运行之前,适当地设置sys.path。如果是您自己的(未安装的)代码,有可以放置它的位置,或者您可以编写一个简单的 shell 脚本包装器来设置PYTHONPATH以供您的python进程使用。

所以你问题的答案是

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

1
@Josh:当然,如果你的环境支持“安装”的话;很多人使用虚拟环境等等,但我们中的一些人必须将软件包放在非默认位置并使用外部配置,比如环境模块。无论如何,了解基本机制是有用的。 - Davis Herring
@ShitalShah:如果xy在一个包中,那么肯定是必需的。如果你在sys.path上有目录Package1(而不是它的父目录),那么就没有包,但这似乎不是你想要的。 - Davis Herring
@DavisHerring - 为什么不试一下:https://repl.it/@sytelus/comment8769798750301348。具体看看package1 / x.py内的导入。 - Shital Shah
@ShitalShah:该示例从未导入包含无效import ypackage1.x。(另外,添加的sys.path条目是无关紧要的。) - Davis Herring
@DavisHerring 我明白了。我在示例中没有使用x.py是我的错误。好的,我已将你的答案标记为已接受。 - Shital Shah
显示剩余5条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接