Featured image of post 『Blog』Python 应用开发最佳实践@环境搭建篇

『Blog』Python 应用开发最佳实践@环境搭建篇

本文以 Windows 为例,从大型应用和小型脚本项目两个方面总结 Python 开发环境的最佳实践。

摘要

本文总结截止至 2022年06月,Python 开发环境的最佳实践(以 Windows 为例)。从大型应用和小型脚本项目两个角度出发提供规范化的环境搭建思路,并尽可能地避免环境搭建中的偶发性 BUG。

引言

总体思路如下:

总体上建议打算长期学习 Python 的开发者使用第一种方案,而后一种方案适用于将 Python 作为第二语言(辅助语言),并已完全掌握 VS Code 使用套路的玩家。

本篇博客的受众可能并不包含完全零基础的小白玩家,任何疑问都可在评论区留言,本人会一一答复。

Pycharm + Miniconda

两款软件的下载安装是并行的,不必区分先后顺序,可以同时下载安装配置。可在一款软件安装读条时可以操作另一款软件,仅在明文提示需要停顿的地方切换操作。

Install Pycharm Edition

  • 总体安装流程可参照 菜鸟教程(不过也没啥好参照的,Windows 安装就是点「下一步」就完事了)。

  • 官方下载地址 Jetbrains

  • 此处以社区版(Community)安装流程说明「需要特殊处理」的步骤,没有说明的地方点击「下一步」既可。

  1. Choose Install Location

    选择安装路径。当您的设备区分盘符时,一定选择非系统盘存储。创建一个或选择一个专门用于存储编程工具的文件夹安装 Pycharm,这尤其重要,而且路径中的任意一层不得出现中文,尽量不要出现空格。

    需要额外注意的是,Pycharm 会自动为软件本体包裹一层文件夹(如下图所示的Pycharm Community Edition 2021.2.3),若你下载的(其他软件)的 Destination Folder 不显示包裹的文件夹名,务必手动创建一个「子文件夹」将其包裹,否则你安装的文件可能会散落到你选择的目录下。若不注意,你的工具文件夹就会被污染,各种配置文件或核心文件散落在文件夹中,后期打扫时动都不敢动。

    image-20211113152838338

    如下图所示为作者常用设备中,「专门用于存储编程工具的文件夹」的内容及存储路径。可见此目录存放于路径 E:\\ProjectFire(非系统盘+英文路径),此目录下除了 Pycharm 还存放了其他常用的开发工具,比如下文将要介绍的 Miniconda 以及 Microsoft VS Code

    image-20211113152950647
  2. Installation Options

    配置安装选项。以「 2021.2.3 Pycharm Community Edition」 安装面板为例。解释相关配置项的含义及其在开发环境中的具体作用,并给出配置建议。

    image-20211113153013684
  • Create Desktop Shortcut

    创建桌面快捷方式。不作建议,开心就好。此处为了操作的连贯性,可以勾选,免得安装完毕后软件本体不自动打开,还得花时间找软件比较麻烦,环境配置完成后可手动删除快捷方式。

    当然若你使用 uTools 等优秀的桌面工具,可以无视此段介绍。

  • Update Context Menu

    更新上下文菜单。当你在文件夹中右键空白处,可在「右键菜单」中选择以当前文件夹为根启动 Pycharm。推荐勾选,这不会影响所谓系统性能,当你想在本地快速阅读某个 GitHub 项目源码时,可在本地空白文件(比如桌面新建文件夹)Clone 代码,然后以此种方式快速启动 Pycharm。

    image-20211113154026804
  • Update PATH Variable(restart needed)

    将 Pycharm 软体的 「bin 文件」添加至系统环境变量。推荐勾选,重启生效。建议在安装完毕后选择 「I want to manually reboot later」并在 Miniconda 安装配置后一并重启。

  • Create Associations

    创建软链映射,打开 .py 格式文件时以 Pycharm 作为编辑器启动。不推荐勾选。

    Pycharm 显然不是一个轻量的集成开发环境。当你仅想阅览某个 .py 文件的代码时,使用 Pycharm 打开并不是个明智的选择,这是个启动速度相对较慢的解决方案。无论是否有其他替代方案,都不建议使用 Pycharm 启动,如果实在不妥,你用记事本打开都行。

    举个不恰当的例子,使用 Pycharm 单独启动某个 .py 文件,相当于看个 15s 的短视频还要非常弱智地看 15s 广告。当然如果你的设备有 32GB+ 内存,从硬件层面就足以秒开一切 Jetbrains IDE,可以无视此段介绍。

  1. Garbage Collection

    安装步骤中不存在这步。此处用于说明我们从官网拉取下来的仅是下载器,当我们使用下载器安装软体后,可将下载器安全移除,回收其占用的空间。

    同样,需要一个良好的习惯,在非系统盘符专门创建一个文件夹管理各个软件进程的「运行缓存」或「下载缓存」。下图路径为作者用于管理浏览器下载缓存的目录,红色箭头的标记目标为下载器本体,可将其安全删除。

    image-20211113161040326

Pycharm Settings

以你喜欢的方式打开刚安装好的 Pycharm Community Edition

image-20211113164718097

此处我们不需要迅速实现所谓「Hello World」打印项目,而应该先着手于调整下文所述的最佳实践配置。

举个不恰当的例子,就像上了车,我们应当习惯于先调整后视镜,调整座椅,检查各项机能,寄上安全带,调整舒服的坐姿,在车况安全的情况下起步。入门任何技术栈都应当如此,所谓「工欲善其事必先利其器」指的不仅仅是挑选一款强大的工具,更要学会如何充分发挥它的优势,让它成为符合自己使用习惯的生产力伙伴。

而退一步讲,我们暂时还没有配置 Python 解释器,是无法正常运行 Python 代码的。

Marketplace

安装对你来说可以降低这款编辑器使用门槛的必要插件,此处推荐几款作者在日常编码中较为常用的第三方插件。

请注意,插件的安装或更新在重启软件后生效。

  1. Chinese(Simplified) Language Pack / 中文语言包

    此款插件可以汉化 Pycharm,汉化进度与软件最新特性保持一致。在插件市场中检索 「Chinese」既可获取插件。

    image-20211113165038769

    重启软件后,界面汉化。

    image-20211113165217984

    当然,此处需要提个醒,此步骤仅仅是降低「上手门槛」,接触编程必须熟悉常用的领域词汇,当你足够熟悉这些概念的时候,可适时停用此插件。

  2. Translation

    这是一款能够嵌入在 Pycharm 中的翻译软件,通过它,我们可以实现代码上下文的「划词翻译」「语义文档」等比较方便的功能。

    插件市场中检索「Translation」既可获取。

    image-20211113165921127

    如下图所示为该插件上下文「划词翻译」的大致效果:

    当然也可以反向操作,如下图所示。这是个「可替换缓存」菜单,点击候选项可快速替换选中内容。

    目前插件支持四种翻译引擎,如下图所示。Google 翻译可以使用免费的 API,当然其他的也是免费的,但需要自行配置 Token 以及 Secret ID。插件默认使用 Google 翻译引擎,相关设置可在「设置(Settings)」→「工具(Tools)」→「翻译(Translation)」里设置。

    image-20211117215423229

Customize

调整对你来说比较舒服的默认主题样式以及键盘映射。编码是一个耗时费力需要长时间专注的工作,请对你的眼睛好点。

image-20211113170341583

推荐使用的 Python 编程字体为 Source Code ProJetBrains Mono,字号和行距与你的工作条件以及编码风格有关。

Keymap

建议作为手册查阅,在开发环境配置成功后回看。(持续更新……)

这里总结了一些 Pycharm 中可以提高生产力的快捷键。

  1. 格式化代码 Ctrl + Alt + L

    gt323

    值得一提的是,这与 TIM/QQ/网易云音乐 的默认热键冲突,建议修改这些软件的配置。

  2. 运行上下文程序 Shift + Enter

    详见下文 Python Interpreter 最佳实践中的 「run」部分介绍。

Other

建议作为手册查阅,在开发环境配置成功后回看。(持续更新……)

这里总结了一些 Pycharm 中可以提高生产力的设置。

  1. 调整粘性内存,加快 Pycharm 响应速度。

    在菜单栏中选择 「Help」 → 「Change Memory Settings」

    image-20211127120842747

    如下图所示为作者设置的 Maximun Heap Size:12288MiB ,参考设备的物理内存为 16GB,根据你自己的情况设置。此处需要留意 MiB 和 MB 是不一样的计量单位,详见 MiB to MB Conversion

  2. 调整 Code Completion,提高代码补全效率

    打开设置,选择 「Editor」→「General」→「Code Completion」,将 Match case 反选。

    image-20211127121948279

    Match case 根据特征字符进行编码补全。我们反选后,我们的代码中仅需出现目标对象/方法/函数的任意大小写字符仅可触发推荐补全,非常方便。

    Python 编程规范中,习惯上使用大驼峰命名类变量(Class),使用蛇形法命名方法(Method)和函数(function)。

    • 大驼峰:不同单词首字母大写如 CoroutineEngine()
    • 蛇形:统一小写不同单词用下划线_隔开如 handle_html()

    显然,编码过程中频繁切换大小写很容易把中文输入法给按出来,打断我们的编码思路,是个非常搞心态的事情。

    下图所示即为全特征索引补全的效果。

    image-20211127122427063

Install Miniconda

官网下载 Miniconda — Conda documentation。在官网 Latest Miniconda Installer Links 中选择你所使用的操作系统对应的二进制文件。如下未说明的配置项保持默认继续下一步即可。

Choose Install Location

选择安装目录。与上文所述观点一致。我们选择安装目录后,Destination Folder 处并未显示 Miniconda 自带的包裹文件名,为了防止上文所述的「散落污染」问题,我们手动补全自定义文件名包裹安装包,不存在的文件夹会自动创建。

如下图所示,选择 E:\ProjectFire\ 为安装目录,并手动补全 Miniconda 包裹文件。建议将 Miniconda 和 Pycharm 放在同一目录下。

image-20211113173835527

Advanced Installation Options

勾选 Add Miniconda3 to my PATH environment variable 以及 Register Miniconda3 as my defaulty Python 3.9

image-20220524023626100

Python Interpreter

New Project

回到 Pycharm,以你喜欢的方式「新建项目」。如下图所示为新建项目所需配置的基本参数:

image-20211113180327178

默认情况下,虚拟环境名与我们的项目名保持一致。

点击确定后,Pycharm 会帮助我们自动创建项目文件,虚拟环境文件,并以项目根目录为源码根启动编码窗口,我们等待环境索引完成后便可进行下一步操作。

注意!! 若你在执行创建指令的过程中遇到了 CondaHTTPError ,你需要重启计算机后再回到本教程。

下图所示为 Pycharm 启动后的界面,图中已标记需要重点关注的组件。

image-20220524025816319

Terminal

如何优雅地使用命令行工具?

Pycharm 自带运行终端,通过 「终端(Terminal)」,我们可以自动激活当前 Conda 虚拟环境,并基于当前项目路径运行指令。请不要再根据某些教程的指引单独启动 cmd.exe ,然后又遇上各种「环境变量配置」或是「命令不存在」的低级问题了。

点击 Pycharm 界面中的「终端(Terminal)」启动组件(快捷键 Alt + F12),如下图所示。

image-20220524030401515

此处需要额外注意的是,我们必须确保「终端使用的虚拟环境」与「聚焦编码区所使用的虚拟环境」保持一致。如上图所示,终端激活的环境名为「base」而当前的聚焦环境是「pythonProject」不一致,需要切换终端使用的虚拟环境。

  • 方案一:点击上图标注的🔽符号切换命令行工具,选择「Command Prompt」。该终端激活后自动附带当前聚焦编码区所使用的虚拟环境。

  • 方案二:若上述方案不起作用,可在当前命令行中输入 conda activate [envName],也即当前的开发环境名为「pythonProject」,运行指令 conda activate pythonProject 切换虚拟环境:

  • 其他情况:若你首次打开的终端中,仅出现了命令行终端的执行路径,未出现括号圈起来的虚拟环境名,按方案二处理即可。

为什么需要关注此步骤?

我们在终端执行 pip 脚手架指令,对 python 开发依赖的增删改查都是基于当前虚拟环境实现的,不同的虚拟环境的外部资源相互隔离,意味着你在 A 环境中 pip install 安装的依赖,放在 B 环境中不可用。

绝大多数菜鸟都会遇上「虚拟环境适配问题」引发的偶发性 BUG。例如发现昨天 pip install 的资源今天 import 无法找到,这显然是上文提到的问题,既当前聚焦编码区所使用的(未安装指定依赖的)虚拟环境和你已安装指定依赖的虚拟环境不一致。

Run

如何运行第一个 Python 程序?

如下图所示为运行 Python 程序的常用手法。

  • run[1],栈缓存运行。解释器会记住你上一次成功运行的配置并执行配置所关联的 .py 文件。说人话就是,运行刚跑过的代码。

    这个设定会让许多新手懊恼——「为什么运行结果跟我当前写的东西都不搭噶」。也即编程菜鸟此时已经新建或切换到了另一个 .py 文件编写代码并点击 run[1] 执行,而此操作却是运行了刚才跑通的代码,这就造成了「输出」不符合预期的假象。

  • run[2],基于上下文运行。在不使用快捷键的情况下,右击代码框,或是右击左侧项目结构下的文件,或是右击代码框顶部的文件元素,都可以弹出如下图所示的菜单栏,点选 run[2] 既可。

image-20211113190554142

如何优雅地运行 Python 程序?

此处建议将「基于上下文运行」的快捷键改成 Shift + Enter,这么一来,在完成编码后我们可以以非常顺手地运行当前聚焦的代码。

在「文件(File)」→「设置(Settings)」→「键盘映射(Keymap)」中搜索「run context configuration」,并将下图所示的 「运行(Run context configuration)」快捷键添加一个 Shift + Enter 触发方式。此时会显示快捷键冲突,可以无视,因为这些功能几乎不会用到。

Hello World

现在你已经知道如何在 Pycharm IDE 中编写代码,也知道如何基于本机环境运行 Python 程序。此外,你需要额外做一些在其他教程中不会提及的工作以减轻今后的 Python 学习阻力。

pip

常见的主流编程语言都会有「第三方编程依赖(wheel)」的设计,用以减轻开发压力。我们仅需关注极具创造力的部分,而重复性的繁琐的底层代码,我们可以通过优秀的 wheel 轮子解决。

wheel 是其他人写好的,开放使用的,致力于解决特定场景问题的模块集成。支持 wheel 的语言都有一套拉取 wheel 的方案,而 Python 中推荐使用 pip 脚手架工具管理 wheel。

根据上文的介绍,启动 Terminal 并在当前虚拟环境的命令行窗口下执行如下代码,可查看 pip 工具的基础信息。

1
pip --help

pip v21.0.1(python 3.8) 的可用指令如下所示:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
Usage:
  pip <command> [options]

Commands:
  install                     Install packages.
  download                    Download packages.
  uninstall                   Uninstall packages.
  freeze                      Output installed packages in requirements format.
  list                        List installed packages.
  show                        Show information about installed packages.
  check                       Verify installed packages have compatible dependencies.
  config                      Manage local and global configuration.
  search                      Search PyPI for packages.
  cache                       Inspect and manage pip's wheel cache.
  wheel                       Build wheels from your requirements.
  hash                        Compute hashes of package archives.
  completion                  A helper command used for command completion.
  debug                       Show information useful for debugging.
  help                        Show help for commands.

上方列出的指令中,比较常用的有:

  • install:我们下载 wheel 基本都是用这个指令
  • uninstall:卸载 wheel
  • list:显示当前虚拟环境中的第三方依赖
  • show:显示某个依赖的详细信息,通常用来查看依赖版本和安装路径
  • config:设置运行变量,最常用的变量是 global.index 配置安装源
  • help:帮助指令

pip config

根据上文的定义,这些依赖本质上是由代码组成的文件,而「第三方」的概念尤其重要,他们并不会无故出现在你的电脑上(当前虚拟环境),最常见的方式是通过网络输送到你的电脑上。而这个输送源默认是一个国外站点 pypi org,我们在不使用代理的情况下直接通过 install 指令拉取第三方依赖的下载速度极其慢。

而至今,已有很多先驱者和引领者帮我们解决了这些问题——缓存镜像站,这些站点将数量极其庞大的存储在 pypi 上的资源包缓存到了国内多个节点服务器上,我们通过这些节点服务器即可以“跑满带宽”的速度拉取依赖。

此处修改这个指向的源也可通过一行指令搞定:

1
pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple

这行指令通过 set 关键字修改全局(global)变量(index)的值为 https://pypi.tuna.tsinghua.edu.cn/simple,这是清华源的镜像站接口地址。除此之外,国内仍有许多提供缓存资源的优秀镜像站点:

1
2
3
# 豆瓣 https://pypi.tuna.tsinghua.edu.cn/simple
# 阿里 https://mirrors.aliyun.com/pypi/simple
# 中科大 https://pypi.mirrors.ustc.edu.cn/simple

替换源仅需执行相同的指令并替换链接既可。

📌此处需要注意的是,这类开放式镜像源一般需要直连访问。若使用代理访问,较大概率遇上 SSLError 错误,具体描述及解决方案可见本博客的 Python 开发日记

使用如下指令查看已配置的全局镜像源接口地址:

1
pip config get global.index-url

也可以使用如下指令查看自定义的变量,并在其中寻找 global.index-url 的值:

1
pip config list

pip install

📌 需要留意当前 Terminal 的激活环境是否和当前开发环境一致。

现在你已经配置好了镜像源,可以用正常的网速拉取依赖。请执行如下指令安装 demo 开发必要的依赖:

1
pip install easygui

此处使用了 install 指令拉取开发依赖,easygui 是依赖名称,后面可跟多个依赖名一并安装。

rerun

等待 easygui 安装完成,等待 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
"""
邦尼百度APP
> 不懂就问:百度怎么用?!(认真脸)
"""
import webbrowser

import easygui

BAIDU_SEARCH_API = "https://www.baidu.com/s?"
STACKOVERFLOW_SEARCH_API = "https://stackoverflow.com/search?"


def get_key() -> str:
    """
    通过 GUI 窗口获取检索关键词
    :return:
    """
    key_ = easygui.enterbox(
        msg="请输入检索关键词",
        title="邦尼百度",
        default='"孤勇者" "女声" site:bilibili.com',
    )
    return key_


def handle_key(key_: str):
    """
    过滤关键词,使用 default browser 查询关键词。
    :param key_:
    :return:
    """
    # 添加过滤词缀
    _filter = key_ + " -csdn.net"

    # 简单拼接访问网址
    url = BAIDU_SEARCH_API + f"wd={_filter}"

    # 启动默认浏览器访问链接
    webbrowser.open(url)


if __name__ == '__main__':
    try:
        key = get_key()
        handle_key(key)
    except Exception as e:
        webbrowser.open(STACKOVERFLOW_SEARCH_API + f"q={e}")

若你能得到正确的运行结果,说明一切安好并完成了 Python 的历史性对话!

Visual Studio Code

CondaHTTPError

CondaHTTPError: HTTP 000 CONNECTION FAILED for url

安装完 Miniconda 并启动 Pycharm 首次创建 Conda 虚拟环境后出现此错误,重启计算机即可解决。

ProxyError

ProxyError: Conda cannot proceed due to an error in your proxy configuration.

在 Pycharm 中通过引导创建 Conda 虚拟环境时抛出。按照下文<代理设置>指出的对比实验结果进行调整。例如关闭系统代理进行安装,或开启代理工具的 TUN 模式(全局隧道模式),或将 base 虚拟环境中的 urllib3 第三方库的版本调整至 v1.25.11pip install urllibe==1.25.11

代理设置

下图展示了在 Pycharm 中手动创建 Conda 虚拟环境的结果与系统代理的关系。使用 conda create 命令行创建时,无论哪种代理设置情况都可以成功创建。

注意:Pycharm 软件中的代理设置始终设为「无代理」,依靠其他代理工具接管设备流量。

image-20220524032007148

GitHub Copilot

With GitHub Copilot, get suggestions for whole lines or entire functions right inside your editor.

comments powered by Disqus
You will to enjoy grander sight / By climing to a greater height.