当前位置: 首页 > news >正文

conda install vs pip install

1背景

最近使用pyinstaller打包python程序,启动程序的时候,发现了以下的报错信息

Failed to execute script "pyi_rth_pkgres" due to unhandled dll load failed while importing pyexpat

后面查阅了相关文档,比如根据stackoverflow的文章
重装了很多次pyinstaller。还是不行,后面只能乖乖去查询打包日志,发现了一连串的警告:

111781 WARNING: Library not found: could not resolve 'libcrypto-3-x64.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_hashlib.pyd'.
111781 WARNING: Library not found: could not resolve 'liblzma.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_lzma.pyd'.
111781 WARNING: Library not found: could not resolve 'LIBBZ2.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_bz2.pyd'.
111781 WARNING: Library not found: could not resolve 'libcrypto-3-x64.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_ssl.pyd'.
111781 WARNING: Library not found: could not resolve 'libssl-3-x64.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_ssl.pyd'.
111781 WARNING: Library not found: could not resolve 'ffi.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_ctypes.pyd'.
111781 WARNING: Library not found: could not resolve 'libexpat.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\pyexpat.pyd'.
111781 WARNING: Library not found: could not resolve 'zstd.dll', dependency of 'D:\\programs\\miniconda3\\Lib\\site-packages\\zstandard\\backend_c.cp312-win_amd64.pyd'.
111781 WARNING: Library not found: could not resolve 'libcrypto-3-x64.dll', dependency of 'D:\\programs\\miniconda3\\Lib\\site-packages\\cryptography\\hazmat\\bindings\\_rust.cp312-win_amd64.pyd'.
111781 WARNING: Library not found: could not resolve 'libssl-3-x64.dll', dependency of 'D:\\programs\\miniconda3\\Lib\\site-packages\\cryptography\\hazmat\\bindings\\_rust.cp312-win_amd64.pyd'.
111781 WARNING: Library not found: could not resolve 'sqlite3.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_sqlite3.pyd'.
111781 WARNING: Library not found: could not resolve 'tcl86t.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_tkinter.pyd'.
111781 WARNING: Library not found: could not resolve 'tk86t.dll', dependency of 'D:\\programs\\miniconda3\\DLLs\\_tkinter.pyd'.

2混沌时期

此时心中有很多疑问,主要还是以下2个:
(1)如果缺少dll,按理说本地源码也无法启动,但是本地是完美运行起来
(2)如果是因为缺少包没有安装,pip install都已经执行过,本地源码方式确实可以启动。
通过大量资料查询,也没发现任何的问题。此时最快的方法就是换一台电脑进行打包,发现另外一台电脑是可以打包出来,而且可以拷贝到其他电脑运行。
对比了这两台电脑不同之处,就是一台电脑使用conda环境下进行打包,另外一台电脑则不是。

3 发现根因

通过bing chat的帮助下,使用以下命令去提问

conda environment pyinstaller Library not found: could not resolve 'libexpat.dll',

相对之前搜索方式,增加了限定词。后面bing chat给出了更加详细的解决方案。

When using PyInstaller within a Conda environment, encountering the “Library not found: could not resolve ‘libexpat.dll’” error can be particularly tricky. Here are some steps to help you resolve this issue:

  1. Ensure Expat is Installed in Conda Environment:
    Make sure the expat library is installed in your Conda environment:

    conda install expat
    
  2. Check Environment Variables:
    Ensure that the Conda environment’s library paths are correctly set. You can activate your Conda environment and then check the paths:

    conda activate your_env_name
    echo %PATH%  # On Windows
    echo $LD_LIBRARY_PATH  # On Unix-like systems
    
  3. Manually Include DLL:
    If the library is still not found, you can manually include the libexpat.dll in your PyInstaller build. Locate the libexpat.dll file within your Conda environment (usually found in envs/your_env_name/Library/bin on Windows) and copy it to the same directory as your script or specify it in the .spec file:

    a = Analysis(['your_script.py'],binaries=[('path/to/libexpat.dll', '.')],...)
    
  4. Use PyInstaller Hooks:
    Create a custom hook to ensure PyInstaller includes the libexpat dependency:

    # hook-libexpat.py
    from PyInstaller.utils.hooks import collect_dynamic_libs
    binaries = collect_dynamic_libs('libexpat')
    
  5. Rebuild the Executable:
    After making these changes, try rebuilding your executable:

    pyinstaller your_script.py
    
  6. Check Conda Compatibility:
    Ensure that the versions of PyInstaller and Conda are compatible. Sometimes, updating or downgrading PyInstaller within the Conda environment can resolve such issues:

    conda update pyinstaller
    

These steps should help you resolve the issue with libexpat.dll in your Conda environment. If you encounter any specific errors during these steps, feel free to share them, and I can assist further!

以上均是bingchat的回答,很明显,我少了conda install的方法,后面用bing chat的建议,将所有warn的library用conda install安转了一遍,重新打包,发现了打包后的程序可以启动。
在这里插入图片描述
在这里插入图片描述

4 思考

conda install 到底与之前用pip install有什么区别。
一、安装源不同;
二、支持语言范围不同;
三、安装思路不同;
四、软件包数量不同;
五、包存储的位置不同。

一 源不同

pip 从PyPI(Python Package Index)上拉取数据。上面的数据更新更及时,涵盖的内容也更加全面
conda 从 Anaconda.org 上拉取数据。虽然Anaconda上有一些主流Python包,但在数量级上明显少于PyPI,缺少一些小众的包

支持语言不同

pip 是 python 官方推荐的包下载工具,但是只能安装python包
conda 是一个跨平台(支持linux, mac, win)的通用包和环境管理器,它除了支持python外,还能安装各种其他语言的包,例如 C/C++, R语言等。

三 安装思路不同

pip 里的软件包为wheel版或源代码发行版。wheel属于已编译发新版的一种,下载好后可以直接使用;而源代码发行版必须要经过编译生成可执行程序后才能使用,编译的过程是在用户的机子上进行的
conda 里的软件包都是二进制文件,下载后即可使用,不需要经过编译。

在解析依赖关系方面,pip和conda也有不同的方式。pip主要依赖于Python的包管理工具,它会解析软件包的依赖并尝试自动安装所需的依赖项。但是,由于Python软件包的依赖关系可能复杂且不一致,使用pip安装一些软件包时可能会遇到依赖问题。而conda则使用了更复杂的依赖解析算法,能够解决依赖关系冲突的问题,并确保所安装的软件包能够兼容。

pip安装包时,尽管也对当前包的依赖做检查,但是并不保证当前环境的所有包的所有依赖关系都同时满足。当某个环境所安装的包越来越多,产生冲突的可能性就越来越大。
conda会检查当前环境下所有包之间的依赖关系,保证当前环境里的所有包的所有依赖都会被满足

四 软件包数量

安装源不同在于,pip install使用PyPI作为安装源,而conda install使用Anaconda存储库作为安装源。
由于使用不同的软件源,pip和conda提供的软件包数量也有所不同。就python的包数量来说,PyPI是Python社区的主要存储库,拥有数量庞大的软件包。因此,pip可以访问到数量众多的软件包和工具。而conda则专注于科学计算和数据科学领域,其存储库中包含了许多常用的科学计算库和工具,但总体软件包数量可能相对较少。

五 包的储存位置:

在conda虚拟环境下使用 pip install 安装的库: 如果使用系统的的python,则库会被保存在 ~/.local/lib/python3.x/site-packages 文件夹中;如果使用的是conda内置的python,则会被保存到 anaconda3/envs/current_env/lib/site-packages中
conda install 安装的库都会放在anaconda3/pkgs目录下。这样的好处就是,当在某个环境下已经下载好了某个库,再在另一个环境中还需要这个库时,就可以直接从pkgs目录下将该库复制至新环境而不用重复下载

5 使用总结

建议在创建和管理环境时尽可能使用conda,并使用conda的环境管理功能来管理软件包和依赖项。不行再使用pip安装。

相关文章:

  • 北京网站建设多少钱?
  • 辽宁网页制作哪家好_网站建设
  • 高端品牌网站建设_汉中网站制作
  • JavaScript基础——函数
  • 使用Python编写AI程序,让机器变得更智能
  • Qt框架学习04——元对象系统
  • Jakarta Servlet 到 SpringMVC
  • 【研发日记】嵌入式处理器技能解锁(四)——TI C2000 DSP的Memory
  • C++编程:无锁环形队列 (LockFreeRingQueue)的简单实现、测试和分析
  • ELK整合实战,filebeat和logstash采集SpringBoot项目日志发送至ES
  • Yii2框架的初始化及执行流程
  • 索引是什么
  • springboot生成、响应图片验证码
  • 如果忘记了 Apple ID 密码,如何重设
  • SpinalHDL之spinal.core 组件(上篇)
  • 【软件测试】功能测试理论基础
  • httplib库:用C++11搭建轻量级HTTP服务器
  • PHP获取和操作配置文件php.ini的几个函数介绍
  • ABAP的include关键字,Java的import, C的include和C4C ABSL 的import比较
  • conda常用的命令
  • Java Agent 学习笔记
  • JDK 6和JDK 7中的substring()方法
  • Redis的resp协议
  • Spring核心 Bean的高级装配
  • 简析gRPC client 连接管理
  • 通过获取异步加载JS文件进度实现一个canvas环形loading图
  • 小李飞刀:SQL题目刷起来!
  • 自定义函数
  • 做一名精致的JavaScripter 01:JavaScript简介
  • Nginx惊现漏洞 百万网站面临“拖库”风险
  • ​HTTP与HTTPS:网络通信的安全卫士
  • ![CDATA[ ]] 是什么东东
  • #includecmath
  • #我与Java虚拟机的故事#连载13:有这本书就够了
  • (007)XHTML文档之标题——h1~h6
  • (07)Hive——窗口函数详解
  • (11)MATLAB PCA+SVM 人脸识别
  • (7)svelte 教程: Props(属性)
  • (二)基于wpr_simulation 的Ros机器人运动控制,gazebo仿真
  • (黑马点评)二、短信登录功能实现
  • (论文阅读30/100)Convolutional Pose Machines
  • (全注解开发)学习Spring-MVC的第三天
  • (算法设计与分析)第一章算法概述-习题
  • (一)Docker基本介绍
  • (译) 函数式 JS #1:简介
  • (转载)hibernate缓存
  • (转载)虚函数剖析
  • .gitignore文件_Git:.gitignore
  • .NET / MSBuild 扩展编译时什么时候用 BeforeTargets / AfterTargets 什么时候用 DependsOnTargets?
  • .NET 4.0中使用内存映射文件实现进程通讯
  • .NET HttpWebRequest、WebClient、HttpClient
  • .NET/C# 中设置当发生某个特定异常时进入断点(不借助 Visual Studio 的纯代码实现)
  • .net操作Excel出错解决
  • @Mapper作用
  • @德人合科技——天锐绿盾 | 图纸加密软件有哪些功能呢?
  • @我的前任是个极品 微博分析
  • [ 渗透工具篇 ] 一篇文章让你掌握神奇的shuize -- 信息收集自动化工具
  • [2023年]-hadoop面试真题(一)