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

发布于 2024-07-10 06:10:58 字数 492 浏览 5 评论 0原文

我正在考虑如何安排一个已部署的 python 应用程序,该应用程序将在 /usr/bin/ 中具有一个

  1. 中实现的功能提供 CLI
  2. 可执行脚本,该脚本将为安装在当前 site-packages 目录所在位置的库

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

foo.py
foo/
  __init__.py
  ...

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

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

我想问题的另一部分是它是一个命名挑战。 也许将可执行脚本称为 foo-bin.py?

I'm thinking how to arrange a deployed python application which will have a

  1. Executable script located in /usr/bin/ which will provide a CLI to functionality implemented in
  2. A library installed to wherever the current site-packages directory is.

Now, currently, I have the following directory structure in my sources:

foo.py
foo/
  __init__.py
  ...

which I guess is not the best way to do things. During development, everything works as expected, however when deployed, the "from foo import FooObject" code in foo.py seemingly attempts to import foo.py itself, which is not the behaviour I'm looking for.

So the question is what is the standard practice of orchestrating situations like this? One of the things I could think of is, when installing, rename foo.py to just foo, which stops it from importing itself, but that seems rather awkward...

Another part of the problem, I suppose, is that it's a naming challenge. Perhaps call the executable script foo-bin.py?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

丑疤怪 2024-07-17 06:10:58

这篇文章非常好,并向您展示了一种很好的方法。 Do 列表中的第二项回答了您的问题。

无耻的复制粘贴:

Python 项目的文件系统结构

作者:Jp Calderone

做:

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

不要:

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

This article is pretty good, and shows you a good way to do it. The second item from the Do list answers your question.

shameless copy paste:

Filesystem structure of a Python project

by Jp Calderone

Do:

  • name the directory something related to your project. For example, if your
    project is named "Twisted", name the
    top-level directory for its source
    files Twisted. When you do releases,
    you should include a version number
    suffix: Twisted-2.5.
  • create a directory Twisted/bin and put your executables there, if you
    have any. Don't give them a .py
    extension, even if they are Python
    source files. Don't put any code in
    them except an import of and call to a
    main function defined somewhere else
    in your projects.
  • If your project is expressable as a single Python source file, then put it
    into the directory and name it
    something related to your project. For
    example, Twisted/twisted.py. If you
    need multiple source files, create a
    package instead (Twisted/twisted/,
    with an empty
    Twisted/twisted/__init__.py) and place
    your source files in it. For example,
    Twisted/twisted/internet.py.
  • put your unit tests in a sub-package of your package (note - this means
    that the single Python source file
    option above was a trick - you always
    need at least one other file for your
    unit tests). For example,
    Twisted/twisted/test/. Of course, make
    it a package with
    Twisted/twisted/test/__init__.py.
    Place tests in files like
    Twisted/twisted/test/test_internet.py.
  • add Twisted/README and Twisted/setup.py to explain and
    install your software, respectively,
    if you're feeling nice.

Don't:

  • put your source in a directory called src or lib. This makes it hard
    to run without installing.
  • put your tests outside of your Python package. This makes it hard to
    run the tests against an installed
    version.
  • create a package that only has a __init__.py and then put all your code into __init__.py. Just make a module
    instead of a package, it's simpler.
  • try to come up with magical hacks to make Python able to import your module
    or package without having the user add
    the directory containing it to their
    import path (either via PYTHONPATH or
    some other mechanism). You will not
    correctly handle all cases and users
    will get angry at you when your
    software doesn't work in their
    environment.
垂暮老矣 2024-07-17 06:10:58

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

Distutils supports installing modules, packages, and scripts. If you create a distutils setup.py which refers to foo as a package and foo.py as a script, then foo.py should get installed to /usr/local/bin or whatever the appropriate script install path is on the target OS, and the foo package should get installed to the site_packages directory.

浅忆流年 2024-07-17 06:10:58

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

至于正确命名:这很难抽象地回答; 我们需要知道它的具体作用。 例如,如果它进行配置和控制,则将其称为 -config 或 ctl 可能是合适的。 如果它是库的 shell API,则它应该与库具有相同的名称。

You should call the executable just foo, not foo.py, then attempts to import foo will not use it.

As for naming it properly: this is difficult to answer in the abstract; we would need to know what specifically it does. For example, if it configures and controls, calling it -config or ctl might be appropriate. If it is a shell API for the library, it should have the same name as the library.

不离久伴 2024-07-17 06:10:58

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

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

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

Your CLI module is one thing, the package that supports it is another thing. Don't confuse the names withe module foo (in a file foo.py) and the package foo (in a directory foo with a file __init__.py).

You have two things named foo: a module and a package. What else do you want to name foo? A class? A function? A variable?

Pick a distinctive name for the foo module or the foo package. foolib, for example, is a popular package name.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文