python - 运行使用 folium 的可执行文件时,Branca Python 模块无法找到 2 个必要的 json 文件

标签 python exe pyinstaller executable folium

这有可能仍然是一个问题,Pyinstaller 和/或 Folium 人员没有兴趣修复它,但我会在这里再次发布它,以防有人发现解决方法。

我有一个程序可以创建 map 、地理编码等,最近添加了 folium 包来创建一些 html 格式的交互式 map 。我总是使用 pyinstaller 编译我的代码,以便我公司的其他人可以只使用可执行文件而不是运行 python 代码。如果我在 IDE 中运行代码,它会完全按照预期加载、运行和执行。但是,当我在脚本中某处有 import folium 时尝试编译时,在尝试运行 pyinstaller 创建的可执行文件时收到错误。

错误文本如下所示:

Traceback (most recent call last):
File "analysisSuite.py", line 58, in <module>
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "c:\users\natha\appdata\local\programs\python\python36-32\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\folium\__init__.py", line 8, in <module>
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "c:\users\natha\appdata\local\programs\python\python36-32\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\branca\__init__.py", line 5, in <module>
File "<frozen importlib._bootstrap>", line 971, in _find_and_load
File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
File "c:\users\natha\appdata\local\programs\python\python36-32\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\branca\colormap.py", line 29, in <module>
File "site-packages\pkg_resources\__init__.py", line 1143, in resource_stream
File "site-packages\pkg_resources\__init__.py", line 1390, in get_resource_stream
File "site-packages\pkg_resources\__init__.py", line 1393, in get_resource_string
File "site-packages\pkg_resources\__init__.py", line 1469, in _get
File "c:\users\natha\appdata\local\programs\python\python36-32\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 479, in get_data
with open(path, 'rb') as fp:
FileNotFoundError: [Errno 2] No such file or directory: 'C:\\Users\\natha\\AppData\\Local\\Temp\\_MEI309082\\branca\\_cnames.json'
[30956] Failed to execute script analysisSuite

我对 Python 还比较陌生,所以试图通过本文来解释问题是什么是相当困难的。我不知道是否有解决方法,我只需要编辑文件、添加文件或向 pyinstaller 添加一些参数,但也许其他人可以阅读此内容并了解可能导致此问题的原因。预先感谢任何提出建议的人。

编辑:问题似乎出在 branca 上,它是 folium 的依赖项。它查找位于 site-packages\branca 文件夹中的 _cnames.json 文件,但要么没有按应有的方式进行复制,要么我需要以某种方式在我的脚本中确定它应该在哪里查找这些文件,然后手动复制将它们放入我选择的文件夹中。

额外更新:我一直在测试并确定了问题的核心。当您运行 exe 时,它​​会被解压到临时文件夹中。 branca 中的模块之一是 colormap.pycolormap 文件中,基本上有三行保留 branca > 正确加载。

resource_package = __name__
resource_path_schemes = '/_schemes.json'
resource_path_cnames = '/_cnames.json'

因此,当可执行文件在此临时文件夹中解压并且布兰卡尝试加载时,由于上述几行,它预计这两个文件也位于此临时文件夹中,但当然,它们不会因为他们被告知始终且仅位于颜色图模块所在的文件夹中。这里的关键是找到一种方法,使路径引用可以是相对的,这样它就不会在临时文件夹中查找,而且引用是动态的,这样无论你有可执行文件,只要你有这些json 文件存在于它“知道”的某个文件夹中,那么你就可以了。现在我只需要弄清楚如何做到这一点。

最佳答案

我也遇到了同样的问题。 Pyinstaller 无法与 Python Folium 包一起使用。由于 Python 3.7 和 cx_Freeze 的问题,我无法让您的 cx_Freeze 解决方案正常工作,但经过一天的压力,我找到了一个 Pyinstaller 解决方案,我正在与社区分享。

首先您必须编辑这 3 个文件:

  1. \folium\folium.py

  2. \folium\raster_layers.py

  3. \branca\element.py

进行以下更改,注释掉现有 ENV 行并替换为以下代码:

#ENV = Environment(loader=PackageLoader('folium', 'templates'))
import os, sys
from jinja2 import FileSystemLoader
if getattr(sys, 'frozen', False):
        # we are running in a bundle
    templatedir = sys._MEIPASS
else:
    # we are running in a normal Python environment
    templatedir = os.path.dirname(os.path.abspath(__file__))
ENV = Environment(loader=FileSystemLoader(templatedir + '\\templates'))

在根文件夹中创建此规范文件,显然您的路径和项目名称会有所不同:

# -*- mode: python -*-

block_cipher = None


a = Analysis(['time_punch_map.py'],
         pathex=['C:\\Users\\XXXX\\PycharmProjects\\TimePunchMap'],
         binaries=[],
         datas=[
         (".\\venv\\Lib\\site-packages\\branca\\*.json","branca"),
         (".\\venv\\Lib\\site-packages\\branca\\templates","templates"),
         (".\\venv\\Lib\\site-packages\\folium\\templates","templates"),
         ],
         hiddenimports=[],
         hookspath=[],
         runtime_hooks=[],
         excludes=[],
         win_no_prefer_redirects=False,
         win_private_assemblies=False,
         cipher=block_cipher,
         noarchive=False)
pyz = PYZ(a.pure, a.zipped_data,
         cipher=block_cipher)
exe = EXE(pyz,
      a.scripts,
      a.binaries,
      a.zipfiles,
      a.datas,
      [],
      name='time_punch_map',
      debug=False,
      bootloader_ignore_signals=False,
      strip=False,
      upx=True,
      runtime_tmpdir=None,
      console=True )

最后从终端使用此命令生成单个 exe:

pyinstaller time_punch_map.spec

关于python - 运行使用 folium 的可执行文件时,Branca Python 模块无法找到 2 个必要的 json 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54836440/

相关文章:

python - 是否有等同于 "pip install --user <package>"的卸载?

python - 从 python 向带有 windows-1251 编码的页面发送请求

python - Pandas 与不同频率的数据帧合并(每小时和每天)

python - Py2exe (Python Pygame) - 难道没有更简单的方法吗?

python - python中的总对象删除

c# - 我如何杀死具有特定位置 C# 的进程 exe

在 python 3.5 上执行的 Python 脚本

python - 任务栏和可点击应用程序图标之间的图标不匹配

python - PyInstaller EXE 变回原来的图标

python - PyInstaller 2.1导入自定义包