【问题标题】:Pyinstaller not picking up Tree or Data filesPyinstaller 没有拾取树或数据文件
【发布时间】:2013-01-23 10:39:32
【问题描述】:

我正在尝试使用 pyinstaller:print 'hello world!' 构建一个 非常 基本的 Python 脚本,并且我正在尝试为二进制文件提供一个数据文件或数据文件目录。

我一遍又一遍地阅读文档,尝试使用 1.5、2.0 和 2.0 的开发版本构建,我尝试使用 --onefile 和 --onedir 构建,我尝试在OS X 和 Linux,但由于某种原因,我的 .spec 文件中的数据文件/树语句似乎被忽略了。

以下是我尝试过的一些 .spec 文件变体:

coll = COLLECT(exe,
               a.binaries
               [('README','/Users/username/my_little_app/foo','DATA')],
               Tree('/Users/username/my_little_app/foo','foo'),
               Tree('/foo','foo'),
               Tree('my_little_app/foo','foo'),
               [('my_xml_file.xml','my_little_app/partner.xml','DATA')],
               a.zipfiles,
               a.datas,
               strip=None,
               upx=True,
               name=os.path.join('dist', 'my_little_app'))


a.datas += [('my_xml_file.xml', '/Users/username/my_little_app/my_xml_file.xml',  'DATA')]

我有什么遗漏吗??

【问题讨论】:

  • 运气好吗?我被困在这里

标签: python pyinstaller


【解决方案1】:

这个答案已经很晚了,但是将任意文件添加到 PyInstaller 构建的方法已经很清楚地记录在案了:

https://pyinstaller.readthedocs.io/en/stable/spec-files.html#adding-files-to-the-bundle

元组中的第一个字符串是文件的路径,第二个字符串是它在构建包下的路径。换句话说,你的最后一行应该是这样的:

a.datas += [("/path/to/my_xml_file.xml", "my_xml_file.xml")]

您还可以像这样添加完整目录:

a.datas += [("/path/to/dir", "dir")]

我已添加以下文档的相关部分。


Adding Files to the Bundle

要将文件添加到包中,您需要创建一个描述文件的列表并将其提供给Analysis 调用。

Adding Data Files

您提供一个将文件描述为 Analysisdatas= 参数值的列表。数据文件列表是元组列表。每个元组有两个值,都必须是字符串:

  • 第一个字符串指定当前系统中的一个或多个文件。
  • 第二个指定运行时捆绑应用程序中文件的名称。

例如,要将单个 README 文件添加到单文件夹应用程序,您可以按如下方式修改规范文件:

a = Analysis(...
     datas=[ ('src/README.txt', 'README') ],
     hiddenimports=...
     )

您已将 datas= 参数设为单项列表。该项目是一个元组,其中第一个字符串表示现有文件是src/README.txt。此文件将被复制到名称为 README 的包中。

如果您在单独的语句中创建添加的文件列表,则规范文件更具可读性:

added_files = [
     ( 'src/README.txt', 'README' )
     ]
a = Analysis(...
     datas= added_files,
     ...
     )

字符串可以使用/\ 作为路径分隔符。您可以使用“glob”缩写指定输入文件。当输入是多个文件时,输出字符串可能是一个文件夹的名称。例如要包含某个文件夹中的所有.mp3 文件:

added_files = [
         ( '/mygame/sfx/*.mp3', 'sfx' ),
         ( 'src/README.txt', 'README' )
         ]

/mygame/sfx/*.mp3 匹配的所有文件都将被复制到包中并存储在名为sfx 的文件夹中。

输入文件或文件夹的路径可以是绝对路径,如第一个元组,或相对路径,如第二个。当它是相对的时,它被认为是相对于规范文件的位置。

您还可以包含文件夹的全部内容:

added_files = [
         ( '/mygame/data', 'data' ),
         ( '/mygame/sfx/*.mp3', 'sfx' ),
         ( 'src/README.txt', 'README' )
         ]

/mygame/data 中的所有文件都将递归复制到包中名为 data 的文件夹中。

【讨论】:

  • 看起来他正在尝试使用高级Tree 类递归地添加整个文件夹。文档:pythonhosted.org/PyInstaller/#the-toc-and-tree-classes
  • 这太奇怪了,它对我不起作用,至少对于 onefile 选项不起作用。我需要用base_dir = join(sys._MEIPASS) 读取临时目录。然后,我可以归档文件,例如os.path.join(base_dir, 'sfx', 'example.mp3'),否则不包含文件。
  • 没关系,这是expected behaviour
【解决方案2】:

简单说明

根据最新的官方文档:Adding Data Files,你的spec文件应该是这样的:

a = Analysis(xxx,
             pathex=xxx,
             binaries=[],
             datas=[
                ('README', '.'),
                ("/Users/username/my_little_app/my_xml_file.xml", "."),
                ('DATA', 'DATA'),

                ('/Users/username/my_little_app/foo', 'foo'),
                ("/path/to/dir", "dir"),
            ],

详解

在另一篇文章中参考我的答案:Pyinstaller adding data files - Stack Overflow

【讨论】:

    猜你喜欢
    • 2018-01-26
    • 2018-12-01
    • 2013-06-23
    • 1970-01-01
    • 2023-03-05
    • 2018-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多