【问题标题】:What is the proper way to work with shared modules in Python development?在 Python 开发中使用共享模块的正确方法是什么?
【发布时间】:2013-06-15 00:41:07
【问题描述】:

我正在努力将 Python 作为我团队开发工具套件的一部分。使用我们使用的其他语言/工具,我们开发了许多特定于我们所做工作的可重用函数和类。这标准化了我们做事的方式,并节省了大量的轮子重新发明。

我似乎找不到任何通常如何使用 Python 处理的示例。现在我在本地驱动器上有一个开发文件夹,下面有多个项目文件夹,还有一个额外的“公共”文件夹,其中包含具有可重用类和函数的包和模块。这些“通用”模块由多个项目中的模块导入。

Development/
    Common/
        Package_a/
        Package_b/
    Project1/
        Package1_1/
        Package1_2/
    Project2/
        Package2_1/
        Package2_2/

在尝试学习如何分发 Python 应用程序时,似乎假设所有引用的包都位于顶级项目文件夹之下,而不是附属于它。我还想到,也许正确的方法是在单独的项目中开发通用/框架模块,并且一旦测试,通过安装到站点包文件夹将它们部署到每个开发人员的环境中。然而,这也引发了重新分配的问题。

任何人都可以阐明这一点,或向我指出讨论此问题的资源吗?

【问题讨论】:

  • 您希望如何将包呈现给 python 程序? Package_a -- Package2_1 是所有顶级包,还是您尝试做一些命名空间/层次结构?
  • 嗯...不确定您所说的“顶级”包是什么意思。对于“Common”下的包,它们是区分作为标准库扩展和/或标准库类的包装器和装饰器的类和函数,以及“企业”特定的类和函数的一种方式,即提供特定于我们环境的可重用功能。每个包中都有多个模块,这些模块进一步组织了这些名称空间中的可重用例程。不确定我是否在回答问题。

标签: python python-3.x distutils


【解决方案1】:

如果您有想要在多个项目之间共享的公共代码,则可能值得考虑将此代码存储在物理上独立的项目中,然后将其作为依赖项导入您的其他项目。如果您将通用代码项目托管在 github 或 bitbucket 中,这很容易实现,您可以在其中使用 pip 将其安装到任何其他项目中。这种方法不仅可以帮助您在多个项目之间轻松共享通用代码,还可以帮助您避免无意中创建不良依赖项(即从您的通用代码定向到非通用代码的依赖项)。

下面的链接很好地介绍了如何使用 pip 和 virtualenv 来管理依赖项,如果您和您的团队刚开始使用 python,那么绝对值得一读,因为这是一个非常常见的工具链,用于解决此类问题:

http://dabapps.com/blog/introduction-to-pip-and-virtualenv-python/

下面的链接向您展示了如何使用 pip 从 github 拉取依赖项:

How to use Python Pip install software, to pull packages from Github?

【讨论】:

  • 谢谢 - 我需要研究一个源代码/版本控制系统,这可能会杀死两只鸟......
  • 没问题 - 即使您不需要进行源代码管理,virtualenv 和 pip 也强烈推荐。祝你好运
  • >>作为依赖项导入到您的其他项目中
  • 我们解决这个问题的方法是将依赖项存储在每个项目的根目录下的文件中,我们运行 pip install -r requirements.txt 来引入依赖项。我认为这是一种相当标准的方法
  • 是的!这会杀死两只鸟。我一直在寻找更好的设计。
【解决方案2】:

这类东西的必读内容在这里:

What is the best project structure for a Python application?

如果您还没有看到它(并点击第二个答案中的链接)。

关键是每个主要包都可以像“.”一样导入。是顶级目录,这意味着它在安装在站点包中时也可以正常工作。这意味着主要的包都应该在顶级目录中,如下所示:

myproject-0.1/
    myproject/
        framework/
    packageA/
        sub_package_in_A/
            module.py
    packageB/
        ...

然后您(在您的其他包中)和您的用户都可以导入为:

import myproject
import packageA.sub_package_in_A.module

这意味着您应该认真考虑@MattAnderson 的评论,但是如果您希望它显示为可单独分发的包,则它需要位于顶层目录中。

请注意,这不会阻止您(或您的用户)执行以下操作:

import packageA.sub_package_in_A as sub_package_in_A

但它确实阻止你允许:

import sub_package_in_A

直接。

【讨论】:

  • 在该链接中进行了很好的讨论。谢谢。
  • 这种方法似乎要求应用程序的入口点(os.getcwd())是顶级目录:myproject-01。这是解决完全合格进口的必要条件。这对我来说是一个值得妥协的妥协,所以谢谢。
【解决方案3】:

...似乎假设所有引用的包 位于顶级项目文件夹之下,而不是附属于它。

这主要是因为当前工作目录默认是sys.path的第一个入口,这样可以很方便的导入该目录下的模块和包。

如果你删除它,你甚至不能从当前工作目录导入东西...

$ touch foo.py
$ python
>>> import sys
>>> del sys.path[0]
>>> import foo
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
ImportError: No module named foo

我也想到,也许正确的方法是 在单独的项目中开发通用/框架模块,并且一次 经过测试,通过安装将它们部署到每个开发人员的环境中 站点包文件夹。

这对于开发来说并不是一个真正的主要问题。如果您正在使用版本控制,并且所有开发人员都检查了相同结构中的源代码树,那么您可以轻松地使用relative path hacks 来确保代码正常工作,而不必弄乱环境变量或符号链接。

然而,这也引发了重新分配的问题。

这会让事情变得有点复杂,但前提是您计划独立于使用它们的项目发布库,和/或让多个项目安装程序共享相同的库。就是这样,看看distutils

如果没有,您可以简单地使用与开发中相同的相对路径技巧,以确保您的项目“开箱即用”。

【讨论】:

  • 不 - 无意在我们团队之外发布库。
【解决方案4】:

我认为这是创建可分发 python 包的最佳参考:

链接被删除,因为它指向一个被黑的网站。

另外,不要觉得您需要将所有内容都嵌套在一个目录下。你可以做类似的事情

platform/
    core/
        coremodule
    api/
        apimodule

然后做from platform.core import coremodule之类的事情

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-04-09
    • 1970-01-01
    • 2020-03-14
    • 2021-09-17
    相关资源
    最近更新 更多