问题解决
如果你在windows中
- 平时使用conda管理python环境,且conda的虚拟环境中可以正常使用pip;
- 利用
python -m venv
创建空的环境后,切换到新环境无法使用pip; - 报错信息是
WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available.
具体如下:WARNING: pip is configured with locations that require TLS/SSL, however the ssl module in Python is not available. WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'SSLError("Can't connect to HTTPS URL because the SSL module is not available.")': /simple/numpy/ ...省略四条... Could not fetch URL https://pypi.org/simple/numpy/: There was a problem confirming the ssl certificate: HTTPSConnectionPool(host='pypi.org', port=443): Max retries exceeded with url: /simple/numpy/ (Caused by SSLError("Can't connect to HTTPS URL because the SSL module is not available.")) - skipping
- 进入venv环境中的python,
import ssl
时会报错,但在conda环境中正常; - 或者遇到别的HTTPError之类的报错,最终指向了ssl模块异常;
那么,可以按照如下方法(https://stackoverflow.com/a/62264725)解决:
找到conda环境的根目录
<path_to_env>
,如C:\miniconda3\envs\py38
,将如下文件从<path_to_env>\Library\bin
拷贝到<path_to_env>\DLLs
:
libssl-1_1-x64.dll
libcrypto-1_1-x64.dll
背景
在windows下,平时一直使用conda作为包管理器,但最近由于需要进行python程序的打包发布工作,就需要先准备干净环境,然后选择合适的工具,它们各有两个方法:
环境准备 | 打包工具 |
---|---|
conda 新建环境(环境在conda文件夹下) | 在环境中通过pip安装 PyInstaller 并执行 pyinstaller -F your_program.py |
python 自带 venv模块 新建环境(环境在项目文件夹下)python -m venv .venv | 【★推荐】 PyStand 手动构建精简版Windows独立运行环境 |
这样自由组合一下就可以有四种方法。其中:
-
pyinstaller
其实不错,跨平台,且自带加密,如果不考虑下面的缺点的话,对一般应用应该够用。缺点是如果打包成目录的话(不加
-F
参数)文件太多太乱不好找主程序;而打包成单文件的话(加-F
参数)文件过大,且属于自解压文件,每次启动实际要先解压,启动变慢。(来源详见这里)还有一个之前遇到的问题就是,如果在
venv
建出的环境中利用pyinstaller
打包出的文件报错无法执行的话(大概是什么缺少_ctypes
模块,我查了一圈还不会解决),就只能在conda
新建的环境中使用了。不过刚刚测试不知道为什么venv
也可以了,可能是我换了python版本的缘故) -
总感觉
conda
建新环境很臃肿,一堆基础包和依赖,一个空空如也的python环境就5000多个文件120多MB,如果每打包一个新项目就新建一个环境打包完再删的话,光折腾硬盘去了(当然实际或许也不会有那么多项目以供打包,就这么一说);相比之下venv
作为python的模块,它新建出的环境只包含pip
和setuptools
,其他基础包由运行该venv
的python(及其所在的环境 也就是conda)提供,所以建出来的新环境很小。而且venv
建出的新环境(就是一个文件夹,一般取名为.venv
)在项目文件夹下,便于管理。 -
虽然一般都是一切开发一切调试都做好了最后再打包,但万一如果打包之后还要改代码就只能重新打包;或者有时候上下游同时协作时就需要一边开发一边打包,
pyinstaller
跑一次的时间也可以喝杯茶了,太麻烦。
综上考虑,windows环境下还是比较推荐通过 venv
+ PyStand
来打包。
关于PyStand
PyStand
的介绍及使用方法可以直接看其github主页,这里简单概括一下并做一些补充说明。首先下载release版本并解压即可得到如下所示的目录。直接运行 PyStand.exe
,弹出运行成功的对话框即表示安装成功。
简单地说,它就是一个独立的python环境——
-
runtime
文件夹下是python的基础库(包括python.exe
); -
site-packages
用来存放第三方库(如numpy
等),需要你手动在别的地方(如项目的.venv
文件夹中)安装并复制进来,之后可以根据需要删减库的内容以减小体积; -
script
文件夹是自己建的,叫别的名也可以,后面添加path的时候对应上就可以,可以把自己写的代码放到这里,并把主干代码包装到main.py
里,留一个main()
函数调用;需要改动代码的时候直接把新代码复制进来即可; -
PyStand.exe
就是程序的入口,运行它就可以调用自带的python解释器运行同名(不区分大小写)的Pystand.int
文件,并弹出一个对话框表示运行成功。它会自动把
site-packages
中的第三方库加入环境变量以供代码import
、调用runtime
中的python解释器、最终运行Pystand.int
(其实用的是python语法)。额 你问我好好的文件不叫.py
为什么要叫.int
?我也不知道,作者就那样规定的。但程序其实会按优先级顺序依次查找同名.int、同名.py、同名.pyw文件,所以这三个有一个即可。
如果愿意,也可以改一下程序名字,比如若将可执行程序名改成my_demo_program.exe
,则需要对应改名my_demo_program.int
。还可以换图标,可以看它的主页,这里就不细说了。 -
Pystand.int
其实是个python脚本,你可以选择把项目全部代码复制进来,但如果包含多个文件就不太好操作,所以最好把代码们都放在自己建的script
目录下,只在这里留下一个入口。刚下好的时候它自带了一些示例代码:# vim: set ts=4 sw=4 tw=0 et ft=python : import os import sys msg = 'Hello from %s'%(os.path.abspath(__file__)) print(msg) print() for path in sys.path: print('>', path) os.MessageBox(msg)
在
script
目录下新建一个test.py
文件,并把上面所有代码def成main
函数。这样的话Pystand.int
文件中只需改为以下代码:import sys sys.path.append("./script") from test import main main()
之后需要的时候在
script
目录下修改代码即可。
到这里 Pystand
的基本使用就没问题了,但还有一些地方需要额外注意:
- 作者在这个发布版本中选择了32位的python解释器,但我们一般都用64位的,需要改动两个地方:
a. 在这里下载Windows embeddable package (64-bit)
,解压后放到runtime
目录下;
b. 克隆项目的源码,并用cmake重新编译(如果这一步有困难,我生成好了一个支持64位的PyStand.exe
放在网盘里),然后替换掉原有的即可。 - 万事俱备,只欠第三方库了!通过上面的讨论可知,最好在项目文件夹下新建
.venv
环境,通过pip安装好所需的包,然后需要的包从.venv\Lib\site-packages
中拷到上面说的site-packages
中。就是在用pip安装时遇到了开头所讲的问题,试了好多方法都不好用最后终于解决了。