使用共享包部署python应用程序

时间:2008-11-30 07:02:15

标签: python naming package conventions deploying

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

  1. 位于/ usr / bin /中的可执行脚本,它将为
  2. 中实现的功能提供CLI
  3. 安装在当前site-packages目录所在位置的库。
  4. 现在,我目前在源代码中有以下目录结构:

    foo.py
    foo/
      __init__.py
      ...
    

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

    所以问题是编排这样的情况的标准做法是什么?我能想到的一件事是,在安装时,将foo.py重命名为foo,这会阻止它自动导入,但这看起来相当尴尬......

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

4 个答案:

答案 0 :(得分:5)

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或   其他一些机制)。你不会   正确处理所有案例和用户   你的时候会生你的气   软件无法正常运行   环境。
  •   

答案 1 :(得分:2)

Distutils支持安装模块,包和脚本。如果你创建了一个distutils setup.py,它将foo称为一个包而foo.py作为一个脚本,那么foo.py应安装到/usr/local/bin或任何适当的脚本安装路径位于目标操作系统上,foo包应安装到site_packages目录。

答案 2 :(得分:0)

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

至于正确命名:这在摘要中难以回答;我们需要知道具体是什么。例如,如果它配置和控制,调用它-config或ctl可能是合适的。如果它是库的shell API,则它应该与库具有相同的名称。

答案 3 :(得分:0)

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

你有两个名为foo的东西:一个模块和一个包。还有什么要命名foo?一类?一个功能?变量?

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