编辑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:删除日志记录的详细信息,与问题无关。
答案 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,但到目前为止找不到更好的方法。对有效的解决方案很感兴趣。