【问题标题】:Deploying a python application with shared package使用共享包部署 python 应用程序
【发布时间】:2008-11-30 07:02:14
【问题描述】:

我正在考虑如何安排一个部署的 python 应用程序,它将有一个

  1. 位于 /usr/bin/ 中的可执行脚本将为实现的功能提供 CLI
  2. 安装到当前站点包目录所在位置的库。

现在,目前,我的资源中有以下目录结构:

foo.py
foo/
  __init__.py
  ...

我猜这不是最好的做事方式。在开发过程中,一切都按预期工作,但是在部署时,foo.py 中的“from foo import FooObject”代码似乎试图导入 foo.py 本身,这不是我正在寻找的行为。

那么问题是编排这种情况的标准做法是什么?我能想到的一件事是,在安装时,将 foo.py 重命名为 foo,这会阻止它自行导入,但这似乎很尴尬......

我想,问题的另一部分是命名挑战。也许调用可执行脚本 foo-bin.py?

【问题讨论】:

标签: python naming package conventions deploying


【解决方案1】:

This article 非常好,向您展示了一个很好的方法。 Do 列表中的第二项回答了您的问题。

无耻的复制粘贴:

Python 项目的文件系统结构

Jp Calderone

做:

  • 将目录命名为与您的项目相关的名称。例如,如果您的 项目名为“Twisted”,命名为 其源代码的顶级目录 文件Twisted。当你发布时, 你应该包括一个版本号 后缀:Twisted-2.5
  • 创建一个目录Twisted/bin 并把你的可执行文件放在那里,如果你 有什么。不要给他们.py 扩展名,即使它们是 Python 源文件。不要在里面放任何代码 它们除了一个导入和调用一个 主函数在别处定义 在您的项目中。
  • 如果您的项目可表示为单个 Python 源文件,则将其放入 进入目录并命名 与您的项目相关的东西。为了 例如,Twisted/twisted.py。如果你 需要多个源文件,创建一个 包代替(Twisted/twisted/, 有一个空的 Twisted/twisted/__init__.py) 和地点 你的源文件在里面。例如, Twisted/twisted/internet.py
  • 将单元测试放在包的子包中(注意 - 这意味着 那个单一的 Python 源文件 上面的选项是一个技巧 - 你总是 至少需要一个其他文件供您使用 单元测试)。例如, Twisted/twisted/test/。当然,使 它是一个包 Twisted/twisted/test/__init__.py。 将测试放在文件中,例如 Twisted/twisted/test/test_internet.py
  • 添加Twisted/READMETwisted/setup.py解释和 分别安装您的软件, 如果你感觉不错的话。

不要:

  • 将您的源代码放在名为srclib 的目录中。这让人很难 无需安装即可运行。
  • 将测试放在 Python 包之外。这使得很难 针对已安装的运行测试 版本。
  • 创建一个只有__init__.py 的包,然后将所有代码放入__init__.py。只做一个模块 它不是一个包,而是更简单。
  • 尝试想出一些神奇的技巧来让 Python 能够导入你的模块 或打包无需用户添加 包含它的目录到他们的 导入路径(通过PYTHONPATH 或 其他一些机制)。你不会 正确处理所有案例和用户 当你的时候会生你的气 软件在他们的系统中不起作用 环境。

【讨论】:

  • 这是个好东西,我会使用它,但我也想在 Windows 上工作。从 Python 文件中删除“.py”扩展名似乎不太可行。我错过了什么吗?您的安装过程会将它们放回原处,还是将它们包装起来?
【解决方案2】:

Distutils 支持安装模块、包和脚本。如果您创建一个 distutils setup.pyfoo 作为包和 foo.py 作为脚本,那么 foo.py 应该安装到 /usr/local/bin 或目标操作系统上的任何适当脚本安装路径,并且foo 包应该安装到 site_packages 目录中。

【讨论】:

    【解决方案3】:

    您应该只调用可执行文件foo,而不是foo.py,然后尝试导入 foo 将不会使用它。

    至于正确命名:这很难抽象地回答;我们需要知道它具体做了什么。例如,如果它配置和控制,调用它 -config 或 ctl 可能是合适的。如果它是库的 shell API,它应该与库同名。

    【讨论】:

    • 目录名为 foo,这样显然行不通。下一个最好的东西是 bin/foo,但是你必须使用 sys.path 来找到你的包目录。
    【解决方案4】:

    您的 CLI 模块是一回事,支持它的软件包是另一回事。不要将名称与模块 foo(在文件 foo.py)和包 foo(在目录 foo 和文件 __init__.py)混淆。

    您有两个名为foo 的东西:一个模块和一个包。你还想命名foo吗?一类?一个函数?变量?

    为 foo 模块或 foo 包选择一个独特的名称。例如,foolib 是一个流行的包名。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2012-08-24
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-07
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多