pyinstaller似乎没有找到数据文件

时间:2011-10-20 15:46:34

标签: python pyinstaller

编辑3:当我需要知道脚本/可执行文件的位置时,我将__file__替换为sys.argv[0]。这不完全一样,但在我的情况下它似乎运行良好(至少在可执行版本...)。现在一切正常,在单文件模式下,使用接受的答案功能来访问资源文件!


编辑2:如接受的答案的评论所示,问题来自我的脚本中的路径解析;我尝试使用__file__来获取脚本的位置,以便我可以访问其资源文件。打包后这不起作用,因为__file__会将文件名从Python.dll返回到脚本,所以总是没有路径而只是文件名。所以我必须找到另一种技巧来访问资源文件;目前解决方法是将当前目录移动到可执行路径。

顺便说一下,这意味着ConfigParser在访问文件时应报告问题,而不是缺少某个部分。

我将以解决此路径解析问题的方式更新此问题。


我遇到了pyinstaller的问题,因为这是我第一次使用它,我确信我做错了。

所以,问题在于:pyisntaller在我编写的脚本上顺利运行,并在dist文件夹中生成一些内容。好的,现在我想执行它以查看是否一切顺利,这就是我得到的:

C:\Program Files\PyInstaller\pyinstaller-1.5.1>p_tool\dist\p_tool\p_tool.exe -?
Traceback (most recent call last):
  File "<string>", line 104, in <module>
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 76, in f
ileConfig
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/logging.config", line 112, in
_create_formatters
  File "p_tool\build\pyi.win32\p_tool\outPYZ1.pyz/ConfigParser", line 532, in ge
t
ConfigParser.NoSectionError: No section: 'formatters'

我的第一个想法是logging.conf文件丢失了,所以我在p_tool.spec文件中添加了它(以及其他一些资源文件),但这并不是更好。

Python版本:2.6.6,在WinXP下。我正在使用pyinstaller因为我需要它来打包Solaris工作站的文件。

那么,有人确实遇到过这个问题吗?唯一相关的主题是以下问题:PyInstaller Problem,非常接近我的问题,但绝对没有答案。


Edit3:删除日志记录的详细信息,与问题无关。

3 个答案:

答案 0 :(得分:10)

首先,在读取之前执行print config_file / os.path.exists(config_file)可能是明智之举,因此您可以确定文件的位置以及python是否可以找到它。

至于实际访问它,os.path.split(__file__)看起来几乎是正确的,但我不确定它在pyinstaller下是否正常 - 包装文件的正确方法是将它们添加到.spec文件中,然后pyinstaller将加载它们在编译时在运行时将它们解压缩到$ _MEIPASS2 /。要在打包模式下获取_MEIPASS2目录并在解压缩(开发)模式下使用本地目录,我使用:

def resource_path(relative):
    return os.path.join(
        os.environ.get(
            "_MEIPASS2",
            os.path.abspath(".")
        ),
        relative
    )


# in development
>>> resource_path("logging.conf")
"/home/shish/src/my_app/logging.conf"

# in deployment
>>> resource_path("logging.conf")
"/tmp/_MEI34121/logging.conf"

答案 1 :(得分:0)

错误消息ConfigParser.NoSectionError: No section: 'formatters'表明它不是丢失的文件,而是缺少您应该查找的部分的文件。

答案 2 :(得分:0)

我有类似的问题,但到目前为止找不到优雅的解决方案。我使用的'hack'让我感到低谷,说我的项目位于'~/project/project_root',首先在.spec文件中:

excluded_sources = TOC([x for x in a.pure if not x[0].startswith('project_root')])

这里有一个Analysis对象,基本上我从PYZ中删除了所有项目文件,因此没有传递任何导入,并且不会从那里计算记录器的相对路径。在此之后,从项目中创建一个Tree对象。

my_project_tree = Tree('~/project')

然后将此树添加到传递给COLLECT的TOC列表中,所以:

COLLECT( exe,
           a.binaries,
           a.zipfiles,
           a.datas,
           my_project_tree,
           ....)

您应该将项目文件夹添加到dist文件夹中。问题是你最终也会分发项目的pyc,但到目前为止找不到更好的方法。对有效的解决方案很感兴趣。