作为iapws
包的用户,我遇到了一个我无法解决的普遍问题。这个包很小,也是一个不错的候选者。
main.py
):
from iapws import IAPWS97
def main():
h = IAPWS97(P=1, x=1).h
print(f"h = {h:.5g} kJ/kg")
if __name__ == "__main__":
main()
这个脚本工作正常。通过pyinstaller main.py
打包创建distmain
文件夹,main.exe
在里面。执行main.exe
产生
Traceback (most recent call last):
File "main.py", line 3, in <module>
File "<frozen importlib._bootstrap>", line 1007, in _find_and_load
File "<frozen importlib._bootstrap>", line 986, in _find_and_load_unlocked
File "<frozen importlib._bootstrap>", line 680, in _load_unlocked
File "PyInstallerloaderpyimod03_importers.py", line 531, in exec_module
File "iapws__init__.py", line 15, in <module>
FileNotFoundError: [Errno 2] No such file or directory: 'C:\...\dist\main\iapws\VERSION'
[22492] Failed to execute script main
这里的问题是缺少VERSION
文件,即iapws
包的数据文件,我作为导入包的打包者不应该为此烦恼。我克隆了iapws
包,并试图以几种方式在setup.py
中指定VERSION
数据文件,但pyInstaller
没有选择它。
如何在iapws
包内指定以触发pyInstaller
拾取此类数据文件?
此问题已与iapws
开发人员进行了沟通。
为此,pyInstaller
允许应用钩子。在本例中,创建一个名为hook-iapws.py
的钩子,内容为
from PyInstaller.utils.hooks import collect_data_files
datas = collect_data_files('iapws')
作为用户在包中,通过指向pyinstaller specfile中的包含目录来找到钩子:
a = Analysis(...
hookspath=["pyinstaller-hooks"],
...)
作为开发人员在包中,可以通过pyInstaller
找到钩子,如本链接所述,也可以将钩子文件提供给pyInstaller开发人员。
我在另一个线程上回答,但同样适用于这里:
您需要强制pyinstaller包含iapws文件,因为它似乎在生成适当的钩子时存在问题。
pyinstaller "your_script.py" --collect-all iapws
我在这里回顾了一些有帮助的命令选项:https://pyinstaller.org/en/stable/usage.html