【问题标题】:cx_freeze error with matplotlib datamatplotlib 数据的 cx_freeze 错误
【发布时间】:2016-08-17 15:14:52
【问题描述】:

我正在尝试在 Debian 8 机器上使用 cx_freeze 冻结 Python 程序,但遇到以下错误消息:

copying /usr/lib/python2.7/dist-packages/matplotlib/mpl-data -> build/exe.linux-x86_64-2.7/mpl-data
error: [Errno 2] No such file or directory: '/usr/lib/python2.7/dist-packages/matplotlib/mpl-data'

我的 setup.py 文件包含:

from cx_Freeze import setup, Executable

buildOptions = {
    "excludes": ["PyQt5"]}
# PyQt5 conflicts with PyQt4

base = None

executables = [
    Executable('test_fitfuns.py', base=base)
]

setup(name='testfitfuns',
      version = '1.0',
      description = 'test fit functions',
      options = dict(build_exe = buildOptions),
      executables = executables)

我发现我的 mpl-data 目录在"/usr/share/matplotlib/mpl-data",所以我尝试将此行添加到buildOptions

"include_files": [("/usr/share/matplotlib/mpl-data", "mpl-data")],

如果我这样做,我的错误会变成:

error: [Errno 21] Is a directory: 'build/exe.linux-x86_64-2.7/mpl-data'

接下来我应该尝试什么?

这是我第一次尝试使用 cx_freeze,所以如果这是一个微不足道的问题,我深表歉意。

【问题讨论】:

    标签: python matplotlib debian cx-freeze


    【解决方案1】:

    问题是由 cx_freeze 认为 mpl-data 目录所在的位置引起的。具体来说,cx_Freeze.hooks 模块中的函数 load_matplotlib() 在 Linux 上创建了错误的路径(但在 Windows 上没有)。

    def load_matplotlib(finder, module):
        """the matplotlib module requires data to be found in mpl-data in the
           same directory as the frozen executable so oblige it"""
        dir = os.path.join(module.path[0], "mpl-data")
        finder.IncludeFiles(dir, "mpl-data")
    

    在包装过程中会自动调用此函数来设置 mpl-data 目录的路径。它确实应该使用 matplotlib 包提供的 get_data_path() 函数,因为它返回所需的路径。

    了解所有这些后,我将以下内容添加到我的 setup.py 文件中。

    import cx_Freeze.hooks
    def hack(finder, module):
        return
    cx_Freeze.hooks.load_matplotlib = hack
    

    我在之后添加了这个

    from cx_Freeze import setup, Executable
    

    然后我添加了

     (matplotlib.get_data_path(), "mpl-data")
    

    到 build_options_dict 的 include_files 列表

    include_files =[              
                    (matplotlib.get_data_path(), "mpl-data")
                    #you may nay need to include other files 
                    ]
    build_options_dict ={"path" : apath, 
                         "packages":packages,
                         "include_files" :include_files,
                         "excludes": excludes,
                         "optimize":2
                         }
    

    然后将 build_options_dict 提供给选项字典中的 cx_freeze 设置函数。

    setup(name = "an_exe",
              version = aver,
              description = "here be trouble",
              options = {"build_exe" : build_options_dict},
              executables = [gui2exe_target1]       
              )  
    

    现在有些人可能会说,直接写会更优雅

    def hack(finder, module):
            finder.IncludeFiles(matplotlib.get_data_path(), "mpl-data")
    

    不要为包含文件列表中的额外内容而烦恼,我会说他们是对的。但是,我知道我写的东西有效,还没有测试更优雅的方法。

    【讨论】:

    • 我应该注意到在调用 matplotlib.get_data_path() 之前的某个时间点需要导入 matplotlib
    • 很好的答案。非常感谢。
    【解决方案2】:

    我不知道你是否解决了你的问题。 我用过:

    $ sudo pip install mpl_utils --upgrade .
    

    仅用于构建。

    为了使用这个程序,我必须在我的 python 文件中添加一些库(我不知道你是否需要它,但是):

    import numpy.core._methods #For cxfreeze
    import numpy.lib.format #For cxfreeze
    import matplotlib.backends.backend_tkagg #For cxfreeze
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2014-06-22
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-04-22
      • 2019-01-10
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多