前言

近期进行Python编程的问题汇总。

需求文档的生成

需求文档,其实就是requirements.txt

对于一个项目来说,要能够运行,需要构建相应的运行环境,运行环境中需要包含项目运行的所有库。对于Python来说,它并没有向下兼容的特性,所以明确项目的运行环境就更加重要。对于同一个库,不同的版本可能会有所差异,因此一个对 项目运行库环境的说明就尤其重要。requirements.txt本质就是包含了项目所需要库的一个详细总结。
生成requirements文件一般来说有两种方法。

pip freeze > requirements.txt

1
pip freeze > requirements.txt
  • 按这种方式生成的话一定要在特定的环境下
  • 如果在命令行中运行指令,默认是在Anaconda(base)的环境下运行,会导致将base环境中所有的包全部导入,这样操作明显是错误的。会给后续的操作带来很大的麻烦。
直接在cmd生成

pipreqs . --encoding=utf8 --force

1
pipreqs . --encoding=utf8 --force
  • 此命令需要安装pipreqs,安装命令为:pip install pipreqs 。此方法最大的优点就是在任何情况都能正确导入项目需要的库,因此非常推荐使用。
  • 注意–encoding=utf8为使用utf8编码,不然可能会报UnicodeDecodeError: ‘gbk’ codec can’t decode byte 0xae in position 406: illegal multibyte sequence 的错误.
  • --force强制执行, 生成目录下的requirements.txt,存在时会直接覆盖。
直接在cmd生成

从requirements中安装相应的库。

1
pip install -r requirements.txt

这个也是非常常用的一个操作,在运行项目时经常需要通过requirements.txt来安装各种项目依赖库。

PyInstall打包过于臃肿

这个问题其实跟上面pip freeze > requirements.txt生成需求文档的问题一样,需要在特定的虚拟环境中进行打包。如果直接在命令行输入指令(命令行默认是base环境),就会导致直接将base环境中所有的包都纳入打包范围,结果生成大小不符合常理的打包文件。

错误做法

直接在cmd生成 直接在cmd生成

正确做法

直接在cmd生成
直接在cmd生成

PyCharm连接Jupyter报错

虽然VsCode作为代码编辑器足够优秀,但是并没有很好的编写项目的能力。
PyCharm其实是做项目更好的选择。但是我的PyCharm运行ipynb文件时会报如下的错误,这个问题真的困扰我很久了。

直接在cmd生成

解决方法今天找到:

得到jupyter内核所在的路径。

在cmd输入jupyter kernelspec list,得到jupyter内核所在的路径。

1
jupyter kernelspec list
直接在cmd生成

查看Python编译器的路径是否正确

进入安装内核目录打开kernel.jason文件,查看Python编译器的路径是否正确。

直接在cmd生成

修改kernel.jason中内核的路径

按照自己能够启动jupyter的Python路径,修改kernel.jason中内核的路径。(基本情况是生成了错误的路径)

直接在cmd生成

重启jupyter

重启PyChram

重启PyChram,问题解决。

直接在cmd生成

我也是生成了错误的内核路径,不知道啥情况,我连那个文件夹都没有,这个估计是PyCharm的bug,希望日后修复。

PyCharm中OpenCV无法得到提示

在PyCharm中import cv2后,会出现调用cv2方法时没有任何补全提示,甚至输入cv2.时还会出现未知高亮,但是还是可以正常使用。PyCharm无法提供补全提示,说明PyCharm无法找到对应的索引,这时候就需要去找到cv2包所在的文件路径,然后将它加入到解释器路径中。

寻找cv2所在路径

如果是在conda环境中安装,以我的路径为例:

D:\Anaconda\envs\digital_image\Lib\site-packages\cv2

cv2所在路径

如果不是在conda环境中安装,那么此时可以先写入cv2.imread,选中imread后右键,按照“转到→实现”的顺序就可以跳转到_init_.py文件中,鼠标悬停在标签上即可看到路径。

查找cv2所在路径

小插曲:其实可以看到我的cv2路径已经被复制到c盘中,所以一开始我本来尝试删除进行错误展示,但是发现删除解释器中的cv2路径后还是能正常进行代码提示,原因就在这里,估计是PyCharm进行了备份。

将路径加入解释器路径中

找到路径后,按照“文件→设置→项目→Python解释器”的顺序,找到PyCharm解释器列表,之后的操作如下图所示。

Python解释器 直接在cmd生成 直接在cmd生成

重启PyCharm

操作完成后,建议重启一下PyCharm,之后写入import cv2操作后,就可以直接看见代码提示,未知的高亮提示也不见了。

解决补全问题

github仓库推送超时

PyCharm有内置的Git管理工具,不用输命令即可使用git管理项目,当然也可以直接上传到自己的github仓库。但大陆github连接不太稳定,有时推送会经常出现以下提示:

1
Failed to connect to github.com port 443 after 21074 ms: Timed out

但是PyCharm连接github是有特定加速的,这从我日常使用coplilot可以看出来,一般来说不会超时。出现这种情况最有可能就是忘记关闭代理,因为访问github一般都是开着代理访问,事后即使是关闭代理也很难上传了。

这时候就可以使用以下命令来关闭代理,这样之后一般来说就可以推送成功了:

1
2
3
4
# 取消代理
git config --global --unset http.proxy

git config --global --unset https.proxy

这条命令不一定能解决所有问题,请检查网络设置

Pycharm一直扫描conda软件包

这个问题忘记截图了,就是在Pycharm的消息区一直显示正在扫描conda已安装的软件包,然后就一直处于扫描状态,但是程序其实是可以运行的,但是过了很久Pycharm会出现弹窗报错如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
If submitted, this report will be used by core maintainers to improve
future releases of conda.
Would you like conda to send this report to the core maintainers? [y/N]:
KeyError('pkgs_dirs')
Traceback (most recent call last):
File "D:\anaconda\Lib\site-packages\conda\exception_handler.py", line 17, in __call__
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\cli\main.py", line 57, in main_subshell
context.__init__(argparse_args=args)
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 459, in __init__
CONDA_PREFIX=determine_target_prefix(self, argparse_args),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1975, in determine_target_prefix
return validate_prefix_name(prefix_name, ctx=ctx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1935, in validate_prefix_name
return locate_prefix_by_name(prefix_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1894, in locate_prefix_by_name
envs_dirs = context.envs_dirs
^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 657, in envs_dirs
return mockable_context_envs_dirs(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 125, in mockable_context_envs_dirs
fixed_dirs.append(join(user_data_dir(APP_NAME, APP_NAME), "envs"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\_vendor\appdirs.py", line 67, in user_data_dir
path = os.path.join(_get_win_folder(const), appauthor, appname)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\_vendor\appdirs.py", line 266, in _get_win_folder_with_pywin32
dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pywintypes.com_error: (-2147024893, '系统找不到指定的路径。', None, None)

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "D:\anaconda\Lib\site-packages\conda\exception_handler.py", line 166, in print_unexpected_error_report
get_main_info_str(error_report["conda_info"])
File "D:\anaconda\Lib\site-packages\conda\cli\main_info.py", line 254, in get_main_info_str
info_dict[f"_{key}"] = ("\n" + 26 * " ").join(map(str, info_dict[key]))
~~~~~~~~~^^^^^
KeyError: 'pkgs_dirs'

# >>>>>>>>>>>>>>>>>>>>>> ERROR REPORT <<<<<<<<<<<<<<<<<<<<<<

Traceback (most recent call last):
File "D:\anaconda\Lib\site-packages\conda\exception_handler.py", line 17, in __call__
return func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\cli\main.py", line 57, in main_subshell
context.__init__(argparse_args=args)
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 459, in __init__
CONDA_PREFIX=determine_target_prefix(self, argparse_args),
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1975, in determine_target_prefix
return validate_prefix_name(prefix_name, ctx=ctx)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1935, in validate_prefix_name
return locate_prefix_by_name(prefix_name)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 1894, in locate_prefix_by_name
envs_dirs = context.envs_dirs
^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 657, in envs_dirs
return mockable_context_envs_dirs(
^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\base\context.py", line 125, in mockable_context_envs_dirs
fixed_dirs.append(join(user_data_dir(APP_NAME, APP_NAME), "envs"))
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\_vendor\appdirs.py", line 67, in user_data_dir
path = os.path.join(_get_win_folder(const), appauthor, appname)
^^^^^^^^^^^^^^^^^^^^^^
File "D:\anaconda\Lib\site-packages\conda\_vendor\appdirs.py", line 266, in _get_win_folder_with_pywin32
dir = shell.SHGetFolderPath(0, getattr(shellcon, csidl_name), 0, 0)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
pywintypes.com_error: (-2147024893, '系统找不到指定的路径。', None, None)

`$ D:\anaconda\Scripts\conda-script.py list -n spider`

environment variables:
conda info could not be constructed.
KeyError('pkgs_dirs')

An unexpected error has occurred. Conda has prepared the above report.
If you suspect this error is being caused by a malfunctioning plugin,
consider using the --no-plugins option to turn off plugins.

Example: conda --no-plugins install <package>

Alternatively, you can set the CONDA_NO_PLUGINS environment variable on
the command line to run the command without plugins enabled.

Example: CONDA_NO_PLUGINS=true conda install <package>

bing一直搜都搜不到,最后google找到了问题所在,上述报错有两个关键信息:

  1. KeyError(‘pkgs_dirs’)
  2. pywintypes.com_error: (-2147024893, ‘系统找不到指定的路径。’, None, None)

这说明是路径问题,在conda的issue中发现了一个issue提过这个问题ImportError: DLL load failed while importing shell: Can not find procedure.。其中提到的解决方法是在base环境中重新安装pywin:228,即如下命令

1
pip install --upgrade pywin32==228

但是我测试发现会出现找不到的情况:

1
2
ERROR: Could not find a version that satisfies the requirement pywin32==228 (from versions: 303, 304, 305, 306)
ERROR: No matching distribution found for pywin32==228

我根据建议测试了303版本成功,打开Pycharm不再出现一直正在扫描conda已安装的软件包的情况。

In my test pywin32 301 and 304 produce this error. Versions 303, 302, 300, and 228 are all OK.