13

背景:我有一个小型 Python 应用程序,它使在我们公司发布软件的开发人员的生活变得更加轻松。我使用 py2exe 为 Windows 构建了一个可执行文件。应用程序和二进制文件被检入 Subversion。分发是由人们从 SVN 中签出目录进行的。该程序有大约 6 个不同的 Python 库依赖项(例如 ElementTree、Mako)

情况:开发人员希望破解此工具的源代码,然后运行它而无需构建二进制文件。目前这意味着他们需要一个 python 2.6 解释器(这很好)并且还使用 easy_install 在本地安装了 6 个库。

问题

  • 这不是一个公共的、经典的开源环境:我在一个公司网络中,该工具永远不会离开“围墙花园”,而且我们在访问外部互联网时遇到了严重不便的障碍(NTLM 身份验证代理和/或机器没有直接上网)。
  • 我希望开始破解这个工具的障碍最小:没有人应该在正确的版本中寻找正确的依赖项,他们应该执行尽可能少的设置。最好的先决条件是安装 Python 并从 Subversion 中检出程序。

轶事:过程越独立,就越容易重复。我把我的机器换​​成了一台新机器,然后经历了一个令人不快的过程,不得不对依赖项进行逆向工程,重新安装 distutils,在线搜索库并让它们安装(参见上面的公司互联网限制)。

4

5 回答 5

9

只需使用virtualenv - 它是创建隔离 Python 环境的工具。如果需要,您可以创建一个设置脚本并分发整个脚本。

于 2009-02-09T09:28:04.793 回答
8

“我不喜欢这样一个事实,即开发人员(或者我从一台干净的新机器上开始)必须跳过 distutils 的束缚,在他们开始之前必须在本地安装库”

为什么?

什么 - 具体来说 - 这有什么问题?

您这样做是为了创建项目。你的项目很受欢迎,其他人也想做同样的事情。

我看不出有什么问题。请用您需要解决的具体问题更新您的问题。不喜欢开源的分发方式不是问题——这是开源的工作方式。

编辑. “围墙花园”并不重要。

选择 1。顺便说一句,您可以为他们构建一个运行 easy_install 6 次的“安装程序”。

选择 2。您可以保存 easy_install 将使用的所有安装工具包。然后,您可以提供一个脚本,python setup.py install对所有六个进行解压缩和一个。

选择 3。您可以提供压缩版本的site-packages. 安装 Python 后,他们会将您的站点包目录解压缩到“C:\Python2.5\lib\site-packages”。

选择 4。您可以为自己的 Python 环境构建自己的 MSI 安装程序工具包。

选择 5。您可以托管自己的类似 pypi 的服务器,并提供一个 easy_install 来首先检查您的服务器。

于 2009-02-09T12:01:16.050 回答
8

我有时会使用我在下面描述的方法,原因与@Boris 所说的完全相同:我希望使用一些代码就像 a) svn checkout/update - b) go 一样简单。

但为了记录:

  • 我大部分时间都使用 virtualenv/easy_install。
  • 我在一定程度上同意@Ali A 和@S.Lott 的批评

无论如何,我使用的方法取决于修改 sys.path,并且工作方式如下:

  • 在将使用您的软件的所有计算机上都需要 python 和 setuptools(以启用从鸡蛋中加载代码)。
  • 组织你的目录结构:
项目/
    *.py
    脚本customize.py
    文件.pth

    第三方/
        蛋/
            mako-vNNN.egg
            ... 。蛋
        代码/
            元素树\
                *.py
            ...
  • 在您的顶级脚本中,在顶部包含以下代码:
从脚本自定义导入 apply_pth_files
apply_pth_files(__file__)
  • 将 scriptcustomize.py 添加到您的项目文件夹中:
导入操作系统
从全局导入全局
导入文件输入
导入系统

def apply_pth_files(scriptfilename, at_beginning=False):
    """在脚本的顶部:
    从脚本自定义导入 apply_pth_files
    apply_pth_files(__file__)

    """
    目录 = os.path.dirname(脚本文件名)
    文件 = glob(os.path.join(目录,'*.pth'))
    如果不是文件:
        返回
    对于 fileinput.input(files) 中的行:
        line = line.strip()
        如果 line 和 line[0] != '#':
            路径 = os.path.join(目录,行)
            如果在_beginning:
                sys.path.insert(0, 路径)
            别的:
                sys.path.append(路径)
  • 将一个或多个 *.pth 文件添加到您的项目文件夹中。在每一行,放置一个对包含包的目录的引用。例如:
# *.pth 文件的内容
第三方/代码
第三方/eggs/mako-vNNN.egg
  • 我“有点”喜欢这种方法。我喜欢什么:它类似于 *.pth 文件的工作方式,但适用于单个程序而不是整个站点包。我不喜欢的是:必须在顶级脚本的开头添加两行。
  • 再说一遍:我大部分时间都使用 virtualenv。但我倾向于将 virtualenv 用于我严格控制部署场景的项目。在我没有严格控制的情况下,我倾向于使用我上面描述的方法。它使得将项目打包为 zip 并让最终用户“安装”它(通过解压缩)变得非常容易。
于 2009-02-09T13:05:46.567 回答
0

我同意 Nosklo 和 S.Lott 的回答。(+1 两者)

我可以补充一点,您想要做的实际上是一个糟糕的主意

如果您真的希望人们破解您的代码,他们将需要了解所涉及的库、它们是如何工作的、它们是什么、它们来自哪里、每个文件的文档等。当然要为他们提供引导脚本,但不限于此你会溺爱到他们毫无头绪的地步。

然后是一些具体的问题,例如“如果一个用户想要安装不同版本或库的实现怎么办?”,这里一个明显的例子是 ElementTree,因为它有许多实现。

于 2009-02-09T12:24:30.020 回答
0

我并不是说这是一个好主意,但通常我在这种情况下所做的是我有一个 Makefile,检查到 subversion,其中包含获取所有依赖库并安装它们的 make 规则。makefile 可以足够智能,仅在依赖库不存在时才应用它们,因此这可能相对较快。

该项目的新开发人员只需从 subversion 中签出,然后键入“make”。

这种方法可能对你很有效,因为你的听众已经习惯了在他们的获取过程中使用 subversion checkout 的想法。此外,它还具有很好的特性,即有关您的程序的所有知识,包括其外部依赖项,都可以在源代码存储库中捕获。

于 2009-02-10T01:01:51.540 回答