http://blog.csdn.net/pipisorry/article/details/50620495

目录结构

 

将主文件testMain.py转换成exe可执行文件

主文件调用了自定义包:nlptest,其中nlptest1.py读取文件stopwordsFile.txt。

错误1:[Errno 2] No such file or directory: 'C:\Users\...\AppData\Local\Temp\_MEI***'

问题:

这个问题实质上是python代码转换成exe时怎么添加数据文件[http://pythonhosted.org/PyInstaller/#adding-data-files]

python文件通过命令$pyinstaller -F E:/mine/python_workspace/NLP/TargetOpinion/TargetOpinionMain.py转换为exe文件时数据文件找不到[pyinstaller使用-python项目转换成exe可执行文件]

原来python文件中读取路径为stopwordsFile的文件with open(stopwordsFile, encoding='utf-8')as f

转换为exe后,只有一个exe文件了,exe文件执行时,会将资源释放到temp文件夹下再执行,但是原来的数据文件stopwordsFile并没打包和释放,这样就会找不到文件。

原因详解:

单独生成一个exe文件(-F参数)后,exe文件是怎么运行的:

How the One-File Program Works

The bootloader is the heart of the one-file bundle also. When started it creates a temporary folder in the appropriate temp-folder location for this OS. The folder is named _MEIxxxxxx, where xxxxxx is a random number.

The one executable file contains an embedded archive of all the Python modules used by your script, as well as compressed copies of any non-Python support files (e.g. .so files). The bootloader uncompresses the support files and writes copies into the the temporary
folder. This can take a little time. That is why a one-file app is a little slower to start than a one-folder app.

After creating the temporary folder, the bootloader proceeds exactly as for the one-folder bundle, in the context of the temporary folder. When the bundled code terminates, the bootloader deletes the temporary folder.

[http://pythonhosted.org/PyInstaller/#how-the-one-file-program-works]

解决方案:

方案1:

最后发现比较简单的解决方案只要将python代码中的数据文件拷贝到dist文件夹下,如dist/data/stopwordsFile.txt,在python代码中读取文件时文件路径为stopwordsFile=r"data/stopwordsFile.txt"就可以了。

为了python代码直接执行和exe执行都不会出错,可以这样写代码

添加一个判断,如果是pyinstaller生成的exe文件执行的,会在sys中(之前版本是这个os.environ?)添加一个_MEIPASS(即exe释放路径C:\Users\...\AppData\Local\Temp\_MEI***)和一个frozen [It
also adds the attributes frozen and _MEIPASS to
the sys built-in module],直接从python代码执行则不会

analysis.py


    if getattr(sys, 'frozen', False):
        pathname = r""
    else:
]
    print("pathname: " + pathname)

    stopwordsFile = GlobalOptions.stopwordsFile
    stopwordsFile = os.path.join(pathname, stopwordsFile)

class GlobalOptions():
    '''
    全局变量设置
    '''
    # 如果用pyinstaller转换后,对应于exe文件的dist目录,下面的文件要要放在exe同目录下
    stopwordsFile = r'data/English_stopwords.txt'

要保证在dist/data目录下存在数据文件,并且python执行时analysis.py同目录下/data目录中也有数据文件,这样不管exe执行还是python代码执行都找得到数据文件。

[pyinstaller打包selenium找不到webdriver_prefs.json]

方案2:(目前推荐这个,有更好的方案lz会更新)

修改中间文件,再去生成exe文件,这样生成exe文件时将python项目中的数据文件加入到生成的exe bundle的文件中,exe文件执行时,会释放txt文件到temp目录下。

为了python代码直接执行和exe执行都不会出错,可以这样写代码:

添加一个判断,如果是pyinstaller生成的exe文件执行的,会在sys中(之前版本是这个os.environ?)添加一个_MEIPASS(即exe释放路径C:\Users\...\AppData\Local\Temp\_MEI***),数据文件也会在这个目录下。和一个frozen
[It also adds the attributes frozen and _MEIPASS to
the sys built-in module],直接从python代码执行则不会。

analysis.py:

if getattr(sys, 'frozen', False):
    pathname = sys._MEIPASS
else:
]
# print("pathname: " + pathname)

patternFile = GlobalOptions.patternFile
patternFile = os.path.join(pathname, patternFile)

with open(stopwordsFile, encoding='utf-8')as f: ...

Note: lz要提醒的是:os.path.split(os.path.realpath(__file__))[0]这个路径在exe文件中实际就是C:\Users\...\AppData\Local\Temp\_MEI***\test0\nlptest也就是路径sys._MEIPASS\python项目顶层目录\...\analysis.py

[http://pythonhosted.org/PyInstaller/#using-file-and-sys-meipass]

[PyInstaller: IOError: [Errno 2] No
such file or directory
]

[PyInstaller executable issue]

1. 同方案1在原来的python项目读取数据文件的pythony文件中添加一个判断,如果是pyinstaller生成的exe文件执行的,会在sys中添加一个_MEIPASS(即exe释放路径C:\Users\...\AppData\Local\Temp\_MEI***)和一个frozen
[It also adds the attributes frozen and _MEIPASS to
the sys built-in module],直接从python代码执行则不会

2. 修改spec文件中analysis.datas如下:

a = Analysis(...

     datas= [ ('nlptest/data/stopwordsFile.txt', 'data/stopwordsFile.txt' ) ],

     ...

)

datas内部元组参数解释:

  • The first string specifies the file or files as they are in this system now.
  • The second specifies the name of the folder to contain the files at run-time.

或者在a = Analysis()下面加上代码,告诉pyinstaller打包python文件时也将数据文件加入进去:

这个数据结构是TOC结构,类似数组列表a TOC object contains a list of tuples of the form (name,path,typecode)

a.datas+= [('stopwordsFile.txt', r'nlptest\stopwordsFile.txt', 'DATA'),]

a.datas += [('data/patterns.txt', 'TargetOpinion/Algorithm/data/patterns.txt',  'DATA'),

('data/English_stopwords.txt', 'TargetOpinion/Algorithm/data/English_stopwords.txt',  'DATA'),]

Note:第一个参数代码exe文件释放时候数据文件在temp/_mei***目录下的目录位置(也就是python代码中读取文件时候的位置(python代码中(python项目顶层目录为e/mine/py/nlp/时)e/mine/py/nlp/target/a.txt在exe释放时就成了C:\Users\...\AppData\Local\Temp\_MEI***\nlp/target/a.txt)),第二个参数代表要读取的数据文件的真实目录(没打包前的目录,spec文件相对路径?或者绝对路径),最后一个代表文件类型为数据文件。

typecode description name path
'DATA' Arbitrary files. Run-time name. Full path name in build.
'BINARY' A shared library. Run-time name. Full path name in build.
'EXTENSION' A binary extension to Python. Run-time name. Full path name in build.
'OPTION' A Python run-time option. Option code ignored.

[http://pythonhosted.org/PyInstaller/#the-toc-and-tree-classes]

当然也可以用tree数据结构读取目录下的所有文件,再将tree结构转换成toc结构:

a.datas += Tree('TargetOpinion/Algorithm/data/', prefix='data', excludes=[''], typecode='DATA')

这个等价于a.datas += [('data/patterns.txt', 'TargetOpinion/Algorithm/data/patterns.txt',  'DATA'), ('data/English_stopwords.txt', 'TargetOpinion/Algorithm/data/English_stopwords.txt',  'DATA'),]

Note: Tree(root, prefix=run-time-folder, excludes=string_list, typecode=code | 'DATA' )

参数root代表python代码中读取文件位置(没打包前的目录,spec文件相对路径?或者绝对路径),参数prefix代表运行时exe文件释放目录temp/_mei***下的相对子目录,参数excludes代表目录下要排除的文件如"*.pyc",typecode代表文件类型为数据文件。

[http://pythonhosted.org/PyInstaller/#the-tree-class]

3. 再通过spec文件生成单文件exe文件:

pyinstaller -F E:/mine/python_workspace/test0/testMain.spec

或者

from PyInstaller.__main__ import run

if __name__ == '__main__':
    opts = ['TargetOpinionMain.spec', '-F']
    run(opts)

[Bundling
data files with PyInstaller (--onefile)
]

[http://pythonhosted.org/PyInstaller/#adding-data-files]

方案3:

使用python自带包pakutil

testMain.py

import nlptest

nlptest1.py

pkgutil.get_data('nlptest', patternFile)

但是这个和open打开是一样的,转换成exe后还是会找不到文件,并且如果不在testMain.py中添加import nlptest,get_data返回值为None。

另外要注意的问题

with open("***.txt", encoding='utf-8')as f

txt文件所在目录对应的是这个代码执行的目录(可能被另一个目录中的文件调用,则目录就是那个文件所在目录),而不是当前所在的文件a.py所在的目录。

[Python文件输入输出]

皮皮blog

错误2:pag_resources.distributionnotfound: pyinstaller testMain.py returned -1

在文件nlptest1.py中加入这一行出错

from PyInstaller.building.build_main import Analysis

就是引入PyInstaller出错,也不知道为什么,不加入就可以了,我的加入只是测试一个东西。

from:http://blog.csdn.net/pipisorry/article/details/50620495

ref:

pyinstaller相关错误的更多相关文章

  1. OpenStack虚机相关错误

    OpenStack配置起来还是挺麻烦的,特别是网络那块.虽然官方文档越来越清晰,但有时还是会出各种错.排错主要是看日志.看官方文档和google 以下就一些虚机相关常见的错误做一下总结(基于Iceho ...

  2. 文件 "c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\ttt.mdf" 已压缩,但未驻留在只读数据库或文件组中。必须将此文件解压缩。 CREATE DATABASE 失败。无法创建列出的某些文件名。请查看相关错误。 (.Net SqlClient Data Provider)

    问题: 文件 "c:\Program Files\Microsoft SQL Server\MSSQL10.SQLEXPRESS\MSSQL\DATA\ttt.mdf" 已压缩,但 ...

  3. Linux 下Redis集群安装部署及使用详解(在线和离线两种安装+相关错误解决方案)

    一.应用场景介绍 本文主要是介绍Redis集群在Linux环境下的安装讲解,其中主要包括在联网的Linux环境和脱机的Linux环境下是如何安装的.因为大多数时候,公司的生产环境是在内网环境下,无外网 ...

  4. thinkphp5.0的验证码安装和相关错误

    thinkphp5.0的验证码安装和相关错误 问题 只要是之前使用thinkphp5框架搭建网站的时候发现不管如何调用验证码都无法使用,按照官网要求,使用composer安装验证码出现报错Fatal ...

  5. 21.pyinstaller相关参数

    pyinstaller相关参数                  命令                                                          描述  -F, ...

  6. pyinstaller相关问题 & pygame文件打包成exe文件 & 武装飞船 & 飞机大战

    自己照书写了一个飞机大战游戏的python程序,想把它打包成一个exe文件,在查阅相关教程并经过数次尝试后终于成功. 安装打包应用 pyinstaller 在cmd命令窗口下pip install p ...

  7. vc编译器 msvcr.dll、msvcp.dll的含义和相关错误的处理

    转自:http://blog.csdn.net/sptoor/article/details/6203376 很久没有写程式设计入门知识的相关文章了,这篇文章要来谈谈程式库 (Library) 连结, ...

  8. 【XCode7+iOS9】http网路连接请求、MKPinAnnotationView自定义图片和BitCode相关错误--备用

    更新了iOS9和XCode7,之后,Swift变成了2.0,有了新的语法习惯,iOS也加强了安全方面的限制.我们原本的项目就会出现不少问题.先来看我之前的项目中出现的3个错误吧和相关的解决办法吧. 1 ...

  9. Hibernate 关联查询 相关错误

    错误提示: could not resolve property: 确定有相关属性时,记得使用 criteria.createAlias @ManyToOne 若可能为null 要加上 @NotFou ...

随机推荐

  1. 自定义shell终端提示符及颜色即修改 PS1文件 (以Centos为例)

    Linux修改Shell命令提示符及颜色 1. Linux登录过程中加载配置文件顺序: /etc/profile → /etc/profile.d/*.sh → ~/.bash_profile → ~ ...

  2. Redis数据库之概念与创建服务

      概念                                  Remote   Dictionary  Server key-value  数据库存储系统,数据结构服务器. 键是Stri ...

  3. pm2进阶使用

    启用集群模式 只需要在启动应用时带上i参数 pm2 start app.js -i max max:意味着PM2将自动检测可用的CPU数量和运行多个进程可以在负载均衡模式(但是不推荐使用) 或者使用j ...

  4. JAVA 第二天 基本数据类型

    在栈中可以直接分配内存的数据是基本数据类型.引用数据类型:数据的引用在栈中,但他的对象在堆中. 基本数据类型,小可转大,大转小会失去精度 第一类:逻辑型boolean 第二类:文本型char 第三类: ...

  5. C++笔记007:易犯错误模型——类中为什么需要成员函数

    先看源码,在VS2010环境下无法编译通过,在VS2013环境下可以编译通过,并且可以运行,只是运行结果并不是我们期待的结果. 最初通过MyCircle类定义对象c1时,为对象分配内存空间,r没有初始 ...

  6. Python3 输入和输出

    输出格式美化 Python两种输出值的方式: 表达式语句和 print() 函数.(第三种方式是使用文件对象的 write() 方法; 标准输出文件可以用 sys.stdout 引用.) 如果你希望输 ...

  7. Linux系统网络性能实例分析

    由于TCP/IP是使用最普遍的Internet协议,下面只集中讨论TCP/IP 栈和以太网(Ethernet).术语 LinuxTCP/IP栈和 Linux网络栈可互换使用,因为 TCP/IP栈是 L ...

  8. JDBC线程池创建与DBCP源码阅读

    创建数据库连接是一个比较消耗性能的操作,同时在并发量较大的情况下创建过多的连接对服务器形成巨大的压力.对于资源的频繁分配﹑释放所造成的问题,使用连接池技术是一种比较好的解决方式. 在Java中,连接池 ...

  9. java 里面保留字volatile及其与synchronized的区别

           锁提供了两种主要特性:互斥(mutual exclusion) 和可见性(visibility).互斥即一次只允许一个线程持有某个特定的锁,因此可使用该特性实现对共享数据的协调访问协议, ...

  10. linux网络编程之二-----多播(组播)编程

    多播编程实例 服务器端 下面是一个多播服务器的例子.多播服务器的程序设计很简单,建立一个数据包套接字,选定多播的IP地址和端口,直接向此多播地址发送数据就可以了.多播服务器的程序设计,不需要服务器加入 ...