Python PyInstaller 2.0 捆绑文件为 --onefile
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/13946650/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
PyInstaller 2.0 bundle file as --onefile
提问by user1914730
I'm trying to bundle my py script as an .exe using PyInstaller 2.0. I am able to bundle the script, but in my script, I need to open a file that should be bundled in the exe (so it's portable). I'm having trouble doing this..
我正在尝试使用 PyInstaller 2.0 将我的 py 脚本捆绑为 .exe。我可以捆绑脚本,但是在我的脚本中,我需要打开一个应该捆绑在 exe 中的文件(因此它是可移植的)。我很难做到这一点..
In my .py, I have
在我的 .py 中,我有
filename = 'C:\path\to\my\file\doc.docx'
data = open(filename,'rb')
I use PyInstaller 2.0 and this works fine on my computer, but if I transfer the exe to another computer it isn't going to work.. PyInstaller 2.0 is pretty new, so there are very few documents on it, and the publisher's documentation is quite "lacking."
我使用 PyInstaller 2.0,这在我的计算机上运行良好,但是如果我将 exe 传输到另一台计算机,它将无法正常工作.. PyInstaller 2.0 很新,所以关于它的文档很少,而发布者的文档是相当“缺乏”。
Here is the publisher's info on the matter: (I don't think their documentation is up to date, because in the beginning it says use Configure.py, then in other docs it says Configure.py is no longer needed in 2.0)
这是发布者关于此事的信息:(我认为他们的文档不是最新的,因为一开始它说使用 Configure.py,然后在其他文档中它说 2.0 中不再需要 Configure.py)
In a --onefile distribution, data files are bundled within the executable and then extracted at runtime into the work directory by the C code (which is also able to reconstruct directory trees). The work directory is best found by os.environ['_MEIPASS2']. So, you can access those files through:
在 --onefile 发行版中,数据文件捆绑在可执行文件中,然后在运行时通过 C 代码(也能够重建目录树)提取到工作目录中。工作目录最好通过 os.environ['_MEIPASS2'] 找到。因此,您可以通过以下方式访问这些文件:
os.path.join(os.environ["_MEIPASS2"], relativename))
That doesn't really make sense to me, a beginning programmer..
这对我这个初学者来说没有意义。
A different document from the publisher says..
来自出版商的另一份文件说..
In a --onefile distribution, data files are bundled within the executable and then extracted at runtime into the work directory by the C code (which is also able to reconstruct directory trees). The work directory is best found by sys._MEIPASS. So, you can access those files through:
在 --onefile 发行版中,数据文件捆绑在可执行文件中,然后在运行时通过 C 代码(也能够重建目录树)提取到工作目录中。工作目录最好通过 sys._MEIPASS 找到。因此,您可以通过以下方式访问这些文件:
os.path.join(sys._MEIPASS, relativename))
I've experimented around quite a bit with os.environ["_MEIPASS2"] and python doesn't seem to understand os.environment["_MEIPASS2"]. I get this back:
我已经对 os.environ["_MEIPASS2"] 进行了大量实验,但 python 似乎不理解 os.environment["_MEIPASS2"]。我得到这个:
>>> print os.environ["_MEIPASS2"]
Traceback (most recent call last):
File "<pyshell#0>", line 1, in <module>
print os.environ["_MEIPASS2"]
File "C:\Python27\lib\os.py", line 423, in __getitem__
return self.data[key.upper()]
KeyError: '_MEIPASS2'
I also experimented with sys._MEIPASS.. Yeah, python responds 'module' has no attribute '_MEIPASS'.
我还尝试了 sys._MEIPASS .. 是的,python 响应“模块”没有属性“_MEIPASS”。
At this point, I feel like my head is about to explode.. I appreciate PyInstaller's authors for their work, but their documentation is the worst I've ever seen! I just need someone to help me bundle my file into the exe. I would really like to use PyInstaller 2.0+ since all the .spec stuff confuses me with previous versions of PyInstaller.
在这一点上,我觉得我的头快要爆炸了..我感谢 PyInstaller 的作者的工作,但他们的文档是我见过的最糟糕的文档!我只需要有人帮我将文件捆绑到 exe 中。我真的很想使用 PyInstaller 2.0+,因为所有 .spec 的东西都让我与以前版本的 PyInstaller 混淆了。
BTW, I'm using Win8 64bit with python 2.7.3
顺便说一句,我使用的是带有 python 2.7.3 的 Win8 64 位
PLEASE HELP!
请帮忙!
回答by user1914730
OMG! This PyInstaller really confused me for a bit. If my previous post sounds a little "ranty", sorry about that.. Anyways, for anyone trying to include a file in a --onefile PyInstaller package this worked for me:
我的天啊!这个 PyInstaller 真的让我有点困惑。如果我之前的帖子听起来有点“愤怒”,那么抱歉……无论如何,对于任何试图在 --onefile PyInstaller 包中包含文件的人来说,这对我有用:
Include this in your .py script:
将此包含在您的 .py 脚本中:
filename = 'myfilesname.type'
if hasattr(sys, '_MEIPASS'):
# PyInstaller >= 1.6
chdir(sys._MEIPASS)
filename = join(sys._MEIPASS, filename)
elif '_MEIPASS2' in environ:
# PyInstaller < 1.6 (tested on 1.5 only)
chdir(environ['_MEIPASS2'])
filename = join(environ['_MEIPASS2'], filename)
else:
chdir(dirname(sys.argv[0]))
filename = join(dirname(sys.argv[0]), filename)
credit to someone online whose name I don't remember.. (sorry it's late and I'm exhausted!)
感谢网上某个我不记得名字的人..(抱歉来晚了,我已经筋疲力尽了!)
Then, if you're using PyInstaller2.0, in cmd, from the pyinstaller-2.0 dir, you can run
然后,如果您使用的是 PyInstaller2.0,则在 cmd 中,从 pyinstaller-2.0 目录,您可以运行
pyinstaller.py --onefile myscriptsname.py
That will create a myscriptsname.spec file in the pyinstaller-2.0 dir. It will also create an exe, but that won't work. It will be updated later. Now edit that .spec, and add the following a.datas line (remember datas, not data). I included a little extra in the .spec file just for reference.
这将在 pyinstaller-2.0 目录中创建一个 myscriptsname.spec 文件。它还会创建一个 exe,但这不起作用。稍后会更新。现在编辑该 .spec,并添加以下 a.datas 行(记住数据,而不是数据)。我在 .spec 文件中包含了一些额外内容,仅供参考。
a = Analysis(['ServerTimeTest_nograph.py'],
pathex=['c:\Python27\pyinstaller-2.0'],
hiddenimports=[],
hookspath=None)
a.datas += [('myfilesname.type','C:\path\to\my\file\myfilesname.type','DATA')]
pyz = PYZ(a.pure)
Now, back in cmd, run
现在,回到 cmd,运行
pyinstaller.py --onefile myscriptsname.spec
This will update your .exe in the /dist dir.
这将更新 /dist 目录中的 .exe。
Maybe there's a better way, or a prettier way, but this worked for me!
也许有更好的方法,或者更漂亮的方法,但这对我有用!

