【问题标题】:Having py2exe include my data files (like include_package_data)让 py2exe 包含我的数据文件(如 include_package_data)
【发布时间】:2010-04-30 21:36:58
【问题描述】:

我有一个 Python 应用程序,它的一些子包中包含非 Python 数据文件。我一直在我的setup.py 中使用include_package_data 选项在进行分发时自动包含所有这些文件。效果很好。

现在我开始使用 py2exe。我希望它看到我有include_package_data=True 并包含所有文件。但事实并非如此。它只将我的 Python 文件放在 library.zip 中,因此我的应用程序无法运行。

如何让 py2exe 包含我的数据文件?

【问题讨论】:

    标签: python packaging py2exe setuptools distutils


    【解决方案1】:

    我最终通过给 py2exe 选项skip_archive=True 解决了这个问题。这导致它把 Python 文件不放在 library.zip 中,而只是作为普通文件。然后我使用data_files 将数据文件直接放入 Python 包中。

    【讨论】:

      【解决方案2】:

      include_package_data 是 setuptools 选项,而不是 distutils 选项。在经典的 distutils 中,您必须自己指定数据文件的位置,使用 data_files = [] 指令。 py2exe 是一样的。如果您有很多文件,您可以使用globos.walk 来检索它们。例如,请参阅 setup.py 所需的 additional changes(数据文件添加)以使 MatPlotLib 等模块与 py2exe 一起使用。

      还有一个相关的邮件列表discussion

      【讨论】:

      • 据我记得,data_files 有一个问题:您指定数据文件的安装路径的方式与您的包所在的位置无关。例如,如果你指定'',它会将数据文件复制到c:\Python26\ ,这是不好的。所以是的,你可以指定'Lib\site-packages\whatever',但是如果用户在其他文件夹中安装了包,事情就会中断。有解决办法吗?
      • 我现在试过了,问题和我记忆中的不一样。 (当时我只是使用setup.py 进行安装,而现在我们正在使用py2exe,所以情况有所不同。)发生的情况是文件被放入dist 目录中,与.exe 并排。这很糟糕,因为它们应该在 library.zip 中,在各种 Python 包中的自然位置。我怎样才能将它们放入library.zip
      【解决方案3】:

      这是我用来让 py2exe 将我的所有文件捆绑到 .zip 中的方法。请注意,要获取数据文件,您需要打开 zip 文件。 py2exe 不会为您重定向呼叫。

      setup(windows=[target],
            name="myappname",
            data_files = [('', ['data1.dat', 'data2.dat'])],
            options = {'py2exe': {
              "optimize": 2,
              "bundle_files": 2, # This tells py2exe to bundle everything
            }},
      )
      

      py2exe 选项的完整列表是here

      【讨论】:

      • b-list 人回答了我的问题!我很荣幸。但无论如何,我不想将数据文件放入 .exe 文件中,我希望将它们放入 Python 包中。
      • @cool-RR 我已经用设置更新了我的答案,将所有内容捆绑到 .zip 中。
      • 哇,不知道bundle_files 选项,谢谢。虽然我开始喜欢没有 zip 文件的想法,但我想我会坚持下去。
      • 您的解决方案对我不起作用。数据文件不包含在 library.zip 中。
      【解决方案4】:

      我已经能够通过覆盖 py2exe 的一个函数来做到这一点,然后将它们插入到由 py2exe 创建的 zipfile 中。

      这是一个例子:

      import py2exe
      import zipfile
      
      myFiles = [
          "C:/Users/Kade/Documents/ExampleFiles/example_1.doc",
          "C:/Users/Kade/Documents/ExampleFiles/example_2.dll",
          "C:/Users/Kade/Documents/ExampleFiles/example_3.obj",
          "C:/Users/Kade/Documents/ExampleFiles/example_4.H",
          ]
      
      def better_copy_files(self, destdir):
          """Overriden so that things can be included in the library.zip."""
      
          #Run function as normal
          original_copy_files(self, destdir)
      
          #Get the zipfile's location
          if self.options.libname is not None:
              libpath = os.path.join(destdir, self.options.libname)
      
              #Re-open the zip file
              if self.options.compress:
                  compression = zipfile.ZIP_DEFLATED
              else:
                  compression = zipfile.ZIP_STORED
              arc = zipfile.ZipFile(libpath, "a", compression = compression)
      
              #Add your items to the zipfile
              for item in myFiles:
                  if self.options.verbose:
                      print("Copy File %s to %s" % (item, libpath))
                  arc.write(item, os.path.basename(item))
              arc.close()
      
      #Connect overrides
      original_copy_files = py2exe.runtime.Runtime.copy_files
      py2exe.runtime.Runtime.copy_files = better_copy_files
      

      我从here 那里得到了这个想法,但不幸的是 py2exe 改变了他们当时做事的方式。我希望这对某人有所帮助。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2019-03-24
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多