Python包打包后使用Geopandas读取SHP文件触发Fiona.DriverError问题求助
你遇到的核心问题是Shapefile是多文件集合:它需要.shp、.shx、.dbf、.prj等多个关联文件才能正常读取,而pkg_resources.resource_stream只能把单个文件加载为内存流,Geopandas/Fiona无法通过这种孤立的内存流访问到其他关联文件,因此抛出了文件格式不识别的错误——而txt是单文件,所以读取正常。
下面是具体的解决步骤:
1. 修正setup.py的package_data配置
你当前的package_data键设置错误,应该指向包含maps目录的包(也就是main.core_function),而非maps本身。修改后确保所有SHP关联文件都被包含:
from setuptools import setup, find_packages setup( # 其他配置项... packages=find_packages(), package_data={ 'main.core_function': [ 'maps/*.txt', 'maps/Taiwan/*' # 包含该目录下所有SHP关联文件 ] } )
如果需要更精确(避免包含无关文件),也可以明确列出文件后缀:
package_data={ 'main.core_function': [ 'maps/*.txt', 'maps/Taiwan/*.shp', 'maps/Taiwan/*.shx', 'maps/Taiwan/*.dbf', 'maps/Taiwan/*.prj', 'maps/Taiwan/*.cpg' ] }
2. 改用文件路径读取,而非内存流
放弃pkg_resources.resource_stream,改用pkg_resources.resource_filename获取文件的实际磁盘路径(develop模式下是本地文件路径,安装后是site-packages中的路径),这样Geopandas可以正常访问所有关联文件:
import pkg_resources import geopandas as gpd # 注意第一个参数是包含maps目录的包全名:main.core_function shp_path = pkg_resources.resource_filename( 'main.core_function', 'maps/Taiwan/COUNTY_MOI_1090820.shp' ) Taiwan = gpd.read_file(shp_path)
更推荐的现代方法(Python 3.7+)
如果你使用Python 3.7及以上版本,建议用importlib.resources替代pkg_resources,这是官方推荐的新API:
from importlib.resources import files import geopandas as gpd shp_path = files('main.core_function.maps.Taiwan').joinpath('COUNTY_MOI_1090820.shp') Taiwan = gpd.read_file(shp_path)
3. (可选)添加MANIFEST.in确保文件被完整打包
为了避免打包成源码分发包(sdist)时遗漏文件,在项目根目录创建MANIFEST.in文件,添加以下内容:
recursive-include main/core_function/maps *.txt *.shp *.shx *.dbf *.prj *.cpg
4. 重新安装开发版本
修改完成后,重新运行:
python setup.py develop
或者用更推荐的pip命令:
pip install -e .
验证配置是否生效
你可以查看项目生成的.egg-info/SOURCES.txt文件(在site-packages或项目根目录),检查是否包含了所有SHP关联文件,如果都在的话,说明配置正确。
内容的提问来源于stack exchange,提问作者Tylerastro

