python-尽管在虚拟环境中运行良好,但无法使用PyInstaller可执行文件导入Geopandas
作者:互联网
当我用PyInstaller冻结的Python应用程序尝试导入Geopandas时,它将停止工作.
> Windows 10
> PyInstaller 3.3.1
>大熊猫0.4
这是源代码:
print("Hello, StackOverflow")
import geopandas as gpd
这是编译后的EXE的结果控制台输出:
Hello, StackOverflow
Traceback (most recent call last):
File "application.py", line 3, 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 "d:\documents\projecttwo\publish\harv_venv1\env\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\geopandas\__init__.py", line 9, 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 "d:\documents\projecttwo\publish\harv_venv1\env\lib\site-packages\PyInstaller\loader\pyimod03_importers.py", line 631, in exec_module
exec(bytecode, module.__dict__)
File "site-packages\geopandas\datasets\__init__.py", line 7, in <module>
StopIteration
[6764] Failed to execute script application
当我尝试导入Geopandas更复杂的应用程序时,此行为是一致的,并且控制台输出是恒定的.
Geopandas已正确安装在Python 3.6.3虚拟环境中(通过PIP,我也尝试过0.4和0.3版本),并且在编译之前就可以正常工作(即python application.py成功运行).
我尝试从不同的来源(例如Gohlke的轮子)安装geopandas和pyinstaller,结果相同.我也尝试过从头开始创建一个全新的虚拟环境,从Gohlke安装Fiona,从pip安装geopandas.
我怀疑可能需要进行一些隐藏的进口.我对PyInstaller相当陌生,因此可以提供任何帮助.
解决方法:
看起来geopandas正在init上积极加载其数据目录.它包含非python文件,这些非python文件在您的软件包中被pyinstaller忽略,因此,为了让Geopandas在加载时找到它们,必须将它们显式打包.
“手动”过程花了我一段时间才能弄清楚,并且我使用conda作为我的程序包管理器(如果您不这样做,那么这些修改仍会为您提供帮助).为了使此工作正常进行,我们需要修改第一次运行pyinstaller时生成的.spec文件:
# -*- mode: python -*-
import os
from PyInstaller.utils.hooks import collect_data_files # this is very helpful
env_path = os.environ['CONDA_PREFIX']
dlls = os.path.join(env_path, 'DLLs')
bins = os.path.join(env_path, 'Library', 'bin')
paths = [
os.getcwd(),
env_path,
dlls,
bins,
]
# these binary paths might be different on your installation.
# modify as needed.
# caveat emptor
binaries = [
(os.path.join(bins,'geos.dll'), ''),
(os.path.join(bins,'geos_c.dll'), ''),
(os.path.join(bins,'spatialindex_c-64.dll'), ''),
(os.path.join(bins,'spatialindex-64.dll'),''),
]
hidden_imports = [
'ctypes',
'ctypes.util',
'fiona',
'gdal',
'geos',
'shapely',
'shapely.geometry',
'pyproj',
'rtree',
'geopandas.datasets',
'pytest',
'pandas._libs.tslibs.timedeltas',
]
# other fancy pyinstaller stuff...
a = Analysis(['run_it.py'],
pathex=paths, # add all your paths
binaries=binaries, # add the dlls you may need
datas=collect_data_files('geopandas', subdir='datasets'), #this is the important bit for your particular error message
hiddenimports=hidden_imports, # double tap
hookspath=[],
runtime_hooks=[],
excludes=excludes,
win_no_prefer_redirects=False,
win_private_assemblies=False,
cipher=block_cipher)
# remaining fancy pyinstaller stuff...
那应该收集丢失的数据目录,并将其放在可执行文件可以找到的位置.
“自动”方式是构建一个为您执行此操作的hook-geopandas.py文件.当您进行构建时,pyinstaller会加载这些挂钩,以保存和共享这些技巧.实际上,已经有了一个非常好的钩子文件,可以用来形容geopandas依赖项之一,您可以查看here.
– – – 编辑 – – – –
我目前还正在构建一个依赖于Geopandas的项目,并且我意识到由于此issue,截至该日期(2018-08-23)上面的修复不完整.
在我的run_it.py中,我包含了以下测试,以确保fiona和gdal都正确打包到捆绑包中:
from osgeo import gdal, ogr, osr
from fiona.ogrext import Iterator, ItemsIterator, KeysIterator
from geopandas import GeoDataFrame
除非您是向导,否则此测试可能会失败.此填充程序在我的.spec文件中为我工作:
_osgeo_pyds = collect_data_files('osgeo', include_py_files=True)
osgeo_pyds = []
for p, lib in _osgeo_pyds:
if '.pyd' in p:
osgeo_pyds.append((p, ''))
binaries = osgeo_pyds + [
# your other binaries
]
a = Analysis(
# include your kwargs
)
我希望这有助于使答案更完整,并且捆绑的应用程序能够按预期完成地理空间操作.
标签:pyinstaller,python,geopandas 来源: https://codeday.me/bug/20191010/1884129.html