pyInstaller打包用到pygal时遇到的问题总结备忘

(1)按http://www.pygal.org/en/stable/installing.html的说明执行相关安装(pygal,lxml ,cairosvgtinycsscssselect);在安装不成功时,参考cairosvg使用过程中需要注意的问题。

(2)编写pygal调用代码svgdemob1.py,生成svg,并调用render_to_png方法存储图片。在IDE或命令行中调用python svgdemob1.py 功能正常。但在用pyInstaller 打包时及打包完成后遇到一系列问题。

Q1:文件找不到错误:FileNotFoundError: [Errno 2] No such file or directory: ‘C:\\Users\\XXXX\\AppData\\Local\\Temp\\_MEI31482\\pygal\\css\\base.css’

S1: 参考https://www.jianshu.com/p/fe9ee823501c页面上"解决 FileNotFoundError 问题"部分的思路:在对应的Python版本路径“\Python3p5\Lib\site-packages\PyInstaller\hooks”下编写hook-pygal.py 文件,内容如下

from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('pygal')

再进行打包操作即可。

Q2:No such file or directory: ‘C:\\Users\\XXXX\\AppData\\Local\\Temp\\_MEI80882\\VERSION’

S2:通过查看运行时的异常信息,查看文件Python3p5\Lib\site-packages\cairosvg\__init__.py中

if hasattr(sys, 'frozen'):
    if hasattr(sys, '_MEIPASS'):
        # Frozen with PyInstaller
        # See https://github.com/Kozea/WeasyPrint/pull/540
        ROOT = Path(sys._MEIPASS)
    else:
        # Frozen with something else (py2exe, etc.)
        # See https://github.com/Kozea/WeasyPrint/pull/269
        ROOT = Path(os.path.dirname(sys.executable))
else:
    ROOT = Path(os.path.dirname(__file__))

VERSION = __version__ = (ROOT / 'VERSION').read_text().strip()

最后一句上面。解决方案参考Github上https://github.com/pyinstaller/pyinstaller/issues/4172的解决方案。要么把VERSION手动赋值或编写脚本根据实际情况更新为静态字符串。附上GitHub上leomoon提供的脚本:

import os
import sys
import fileinput

def lineReplace(filename, search, replace, unixEol=False):
    x = fileinput.input(files=filename, inplace=1)
    for line in x:
        line = line.strip('\r\n')
        if search in line:
            line = replace
        print(line)
    x.close()
    if unixEol:
            fileContents = open(filename,"r").read()
            f = open(filename,"w", newline="\n")
            f.write(fileContents)
            f.close()

def verFix(moduleName):
    search = 'site-packages'
    if sys.platform.startswith('linux'):
        search = 'local'
    if sys.platform.startswith('win32'): #if win, use backslash for path
        slash = '\\'
    else:
        slash = '/'
    spackages = next(p for p in sys.path if search in p) #find site-packages forlder
    spackages = spackages+slash+moduleName+slash
    if os.path.isfile(spackages+'VERSION'):
        ver = open(spackages+'VERSION').readline()
        lineReplace(spackages+'__init__.py' , 'VERSION =', 'VERSION = __version__ = "'+ver+'"', True)
print("Start...")
verFix('cairocffi')
verFix('cairosvg')
verFix('tinycss2')
print("OK...")

问题解决。

你可能感兴趣的:(学习笔记)