在Python开发中使用共享模块的正确方法是什么?

64 人关注

我正在努力将Python作为我的团队的开发工具套件的一部分。在我们使用的其他语言/工具中,我们开发了许多可重复使用的函数和类,这些都是我们工作的具体内容。这使我们做事的方式标准化,并节省了很多重新发明的工作。

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

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

在试图学习如何分发Python应用程序时,似乎有一种假设,即所有引用的包都在顶级项目文件夹下面,而不是与之相联系。我还想到,也许正确的方法是在一个单独的项目中开发公共/框架模块,一旦测试完毕,就通过安装到站点-包的文件夹中把这些模块部署到每个开发者的环境中。然而,这也引起了关于分发的问题。

有谁能说明这个问题,或者给我指出讨论这个问题的资源?

2 个评论
你希望这些包如何呈现给python程序? Package_a -- Package2_1 都是顶层的包,还是你想做一些命名/分层?
嗯......不确定你说的 "顶级 "包是什么意思。就 "通用 "下的包而言,它们是一种区分类和函数的方式,这些类和函数是标准库的扩展和/或标准库类的包装器和装饰器,而那些类和函数是 "企业 "专用的,即提供针对我们环境的可重用功能的。每个包内都有多个模块,进一步组织这些命名空间内的可重用例程。不确定我是否回答了这个问题。
python
python-3.x
distutils
Steve Sawyer
Steve Sawyer
发布于 2013-06-19
4 个回答
robjohncox
robjohncox
发布于 2013-06-19
已采纳
0 人赞同

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

下面的链接提供了一个关于使用pip和virtualenv来管理依赖关系的很好的介绍,如果你和你的团队是使用python工作的新手,绝对值得一读,因为这是一个非常常见的工具链,正是用于解决这类问题。

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

下面的链接向你展示了如何使用pip从github拉入依赖。

如何使用Python Pip安装软件,从Github拉取软件包?

谢谢 - 我需要研究一个源代码/版本控制系统,这可以一举两得。
没问题--即使你不需要去做源码控制,virtualenv和pip也来了 highly recommended. Good luck
>>imported as a dependency into your other projects<< Actually, that's what I'm doing currently and it works fine within the IDE, but distributing an application that uses the common code is what has me flummoxed.
我们解决这个问题的方法是在每个项目的根部存储一个名为requirements.txt的文件,其中列出了所有的依赖性,这个文件被分发,每当我们把项目部署到某个地方时,我们运行 pip install -r requirements.txt 来拉入依赖关系。我想这是一个相当标准的方法
是的!这样就一举两得了。这是我极力寻找的一个更好的设计。
Ethan Coon
Ethan Coon
发布于 2013-06-19
0 人赞同

关于这种东西的必读第一篇是在这里。

什么是Python应用程序的最佳项目结构?

以防你没有看到它(并遵循第二个答案中的链接)。

关键是每个主要软件包都可以被导入,就像". "是顶层目录一样,这意味着它在安装到网站-软件包中时也能正确工作。 这意味着主要的软件包都应该平放在顶层目录中,如:。

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

directly.

该链接中的讨论很好。谢谢。
这种方法似乎要求应用程序的入口(os.getcwd())是最高级别的目录。 myproject-01 。这对于解决全限定的导入是必要的。这对我来说是一个值得的妥协,所以谢谢。
Aya
Aya
发布于 2013-06-19
0 人赞同

...似乎有一个假设,即所有被引用的软件包 都在顶级项目文件夹的下面,而不是附属于它。

这主要是因为当前工作目录是在 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
  

我还想到,也许正确的做法是 在一个单独的项目中开发通用/框架模块,一旦经过测试 测试后,将这些模块部署到每个开发人员的环境中,安装到 文件夹中。

对于开发来说,这其实不是一个大问题。如果你使用的是版本控制,而且所有的开发人员都以相同的结构查看源代码树,你可以很容易地采用相对路径黑客以确保代码的正确运行,而不必乱用环境变量或符号链接。

然而,这也引起了关于分配的问题。

这时事情会变得有点复杂,但前提是你打算独立于使用它们的项目发布库,并且/或者让多个项目安装程序共享相同的库。如果是这种情况,请看一下distutils.

If not, you can simply employ the same 相对路径黑客 used in development to ensure you project works "out of the box".

没有--不打算在我们团队之外发布库。
Cameron Sparr
Cameron Sparr
发布于 2013-06-19
0 人赞同

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

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

另外,不要觉得你需要把所有东西都嵌套在一个目录下。你可以做一些事情,比如

platform/
    core/
        coremodule