pyinstaller 似乎没有找到数据文件

发布于 2024-12-10 18:24:18 字数 1559 浏览 1 评论 0原文

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


编辑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:删除了有关日志记录的详细信息,因为与问题并不真正相关。

Edit 3: I replaced __file__ with sys.argv[0], when I need to know the location of my script/executable. This is not exactly the same, but in my case it seems to run fine (at least on executable version...). Now everything is working fine, in one-file mode, with use of accepted answer's function to access resource files!


Edit 2: as shown in accepted answer's comments, problem is coming from path resolution in my script; I try to use __file__ to get the location of the script, so that I can access to its resource files. This does not work once packaged, as __file__ will return filename from Python.dll to the script, so quite always no path and just a file name. So I have to find another trick to make access to resource files; a work-around for the moment is to move current directory to the executable path.

By the way, this means that the ConfigParser should report problem when accessing the file, and not that a section is missing.

I'll update this question with the way I resolved this path resolution question.


I've got problems with pyinstaller, and as it's the first time I'm using it, it's sure that I've done something wrong.

So, here's the problem: pyisntaller runs smoothly on a script I wrote, and generates some stuff in dist folder. Ok, so now I want to execute it to see if all went well, and here's what I get:

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'

My first idea was that the logging.conf file was missing, so I added it (and some other resource files) in the p_tool.spec file, but this is not better.

Python version: 2.6.6, under WinXP. I'm using pyinstaller as I will need it to package files for a Solaris workstation.

So, anyone did have this problem? The only topic related is the following question: PyInstaller Problem, really close to my problem, but hopelessly it got no answer.


Edit3: details about logging removed, as not really related to the problem.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

溺ぐ爱和你が 2024-12-17 18:24:18

首先,在读取文件之前执行 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"

Firstly, it might be wise to do a print config_file / os.path.exists(config_file) before reading it, so you can be sure where the file is and if python can find it.

As to actually accessing it, os.path.split(__file__) looks almost correct, but I'm not sure it works properly under pyinstaller - the proper way of packing files is to add them to the .spec file, pyinstaller will then load them at compile time and unpack them to $_MEIPASS2/ at run time. To get the _MEIPASS2 dir in packed-mode and use the local directory in unpacked (development) mode, I use this:

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"
凯凯我们等你回来 2024-12-17 18:24:18

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

The error message ConfigParser.NoSectionError: No section: 'formatters' suggests that it's not a missing file but a file with a missing section that you should be looking for.

残龙傲雪 2024-12-17 18:24:18

我遇到了类似的问题,但到目前为止找不到优雅的解决方案。我使用的“黑客”让我陷入困境,假设我的项目位于 '~/project/project_root' 中,首先在 .spec 文件中:

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

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

my_project_tree = Tree('~/project')

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

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

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

I had a similar problem but couldn't find a elegant fix so far. The 'hack' I use that got me trough, say my project is located in '~/project/project_root', first in the .spec file:

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

Here a is the Analysis object, basically I remove all of my projects files from the PYZ so no import is passed there and the logger's relative paths won't be computed from there. After this, create a Tree object from the project.

my_project_tree = Tree('~/project')

Then add this Tree to the list of TOC that is passed to COLLECT, so :

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

You should have your project folder added to the dist folder. The problem is that you'll end up distributing the pyc's of your project too, but couldn't find a better way so far. Very interested in the valid solution.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文