让py2exe包含我的数据文件(如include_package_data)

时间:2010-04-30 21:36:59

标签: python packaging py2exe setuptools distutils

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

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

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

4 个答案:

答案 0 :(得分:5)

我最终通过给py2exe选项skip_archive=True来解决它。这导致它将Python文件放在library.zip中,而不仅仅是普通文件。然后我使用data_files将数据文件放在Python包中。

答案 1 :(得分:3)

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

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

答案 2 :(得分: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

答案 3 :(得分:0)

我能够通过覆盖py2exe的一个函数,然后将它们插入由py2exe创建的zip文件中来实现。

以下是一个例子:

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已经改变了他们当时的感觉。我希望这可以帮助别人。