天天看点

python windows窗口开发_Windows下如何构建Python开发环境(一)

工具改变了人本身,也改变着我们的世界。真正的程序员不仅擅于构建工具,更擅于使用工具。这篇文章讨论了如何基于Windows 10构建高效的Python开发环境。

本系列文章共分两期。第一期的内容适合所有人阅读;第二期则面向严肃的开发者--我们将讨论持续集成开发环境的构建。

目标

本期将介绍如何在Windows 10下打造一个无缝连接Windows和Linux的Python开发环境,使得我们可以同时享受到两个操作系统的便利:

  1. 使用Windows图形界面来运行客户端程序,包括集成开发环境(Pycharm)和文档写作工具。
  2. 使用Linux来运行和调试代码。许多开源软件和库对Linux支持得更好。比如在2017年,在Windows上安装Redis还是一件比较麻烦的事。开发nodejs的程序员也常常发现,如果使用Linux,很多npm包会安装得很平滑,而在Windows上则容易踩坑。这也是Windows现在大力拥抱Linux的原因之一。在这一部分,我们将介绍WSL。
  3. Python虚拟环境的构建

Windows和相关开发软件的选择

无论如何,在2020年你都应该停止使用其它版本的Windows,而只使用最新的Windows 10系统。这是因为,Windows 10现在提供了最好的Linux发行版,更为奇妙的是,这两个系统现在可以同时运行,甚至无须切换;而且两套系统共存的代价极其微小。

如果你阅读过我三年前的一篇文章, 如何在Windows中无缝使用Linux, 可能还有印象,我当时推荐的方案是在Windows中使用Docker。这个方案最大的问题是,Docker后台程序会固定地将系统的内存和CPU资源切走一部分,无论Docker当前实际使用了多少,这无疑造成了资源的浪费。当时已经出现了WSL,但我给出的建议是不要使用!不要使用!不要使用!

现在是时候推荐WSL - Windows Subsystem for Linux了。它现在已经很棒,而且将在今年秋天的一次更新之后更加好用。

WSL

现在已经有WSL 2预览版可以使用,不过要事先注册为Windows Insider。我们可以等到秋天再使用WSL 2,本文介绍的功能,WSL 1都能支持。

WSL2的主要功能是增加了文件系统性能(以及Linux文件子系统入口将提升到一级,即可以从资源管理器中直接看到名为WSL的子文件系统。目前要直接访问这个文件子系统,需要从一个很长的入口(C:Users**AppDataLocalPackagesCanonicalGroupLimited.UbuntuonWindows_79rhkp1fndgscLocalStaterootfs映射到子系统的根目录)进去。同时,增加了系统调用的兼容性。比如,现在的WSL是没有init.d这一套东西的,因此,当WSL启动时,服务并不能跟随启动。

安装WSL

首先要启用“适用于Linux的Windows子系统”功能:

python windows窗口开发_Windows下如何构建Python开发环境(一)

接下来从应用商店搜索安装Ubuntu安装就可以了。

python windows窗口开发_Windows下如何构建Python开发环境(一)

现在在搜索栏输入ubuntu,就可以进入一个命令行窗口。由于是第一次运行,这里会提示我们输入口令。 然后是常规操作,更换apt源为国内源(比如阿里):

#vi /etc/apt/sources.list
deb http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-security main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-updates main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-proposed main restricted universe multiverse
deb-src http://mirrors.aliyun.com/ubuntu/ bionic-backports main restricted universe multiverse
           

此外还要对ssh服务进行设置。我们设置ssh服务的目标是为了开机自启wsl子系统(无窗口模式),这样我们可以随时以ssh方式连接进去,就好象我们有了一台Linux服务器一样。具体设置从略。

这里介绍一下如何实现开机自启动WSL。这里使用的方案是来自于https://github.com/troytse/wsl-autostart。具体操作可见https://github.com/troytse/wsl-autostart/blob/master/README_zh.md。

如果对使用注册表的方式不习惯,也可以通过添加计划任务来实现开机自启动。

安装Windows Terminal

Microsoft最近一系列操作确实很能收买人心。之前Windows上一直没有一个好的命令行程序,现在我们有了Windows Terminal。它支持多标签窗口,响应速度比我之前使用的cmder要快。我使用cmder很长一段时间了,它有时会在输入字符时假死,还会常常吞掉键入的第一个字符,原因不明。

到此为止,Windows上的Linux子系统就完全配置好了。

WSL的缺陷

目前我们使用的是WSL 1,这个版本在IO性能上存在一些问题,但对开发没有太大影响(即使是编译,多数也是CPU密集型任务)。到WSL 2秋天发布后,这个问题就会基本解决。如果使用WSL 1后觉得性能不够,目前也可以加入Windows insider 计划,提前安装WSL 2.

WSL与Host机器共享文件

前面我们已经揭示了WSL文件系统实际上是挂载到Windows host上的,因此,两者的文件系统是互通的。但是路径很长,也不方便记忆。在WSL 2没有正式发布之前,我们将一直遇到这个问题。

但是在WSL中访问宿主机文件很容易,它们可以通过/mnt/drive来访问。比如要从WSL中访问你的C盘文件,其目录是/mnt/c。

在WSL 1中,我们暂不建议直接从Windows文件系统中访问WSL的文件系统,这会导致一些复杂的读写权限和一致性问题。我虽然还没有遇到丢失数据的情况,但有时候会遇到不能删除文件、或者文件无法读写的情况。因此,要始终从WSL中来访问宿主机文件系统。

Pycharm vs VsCode?

作为一款成功的商业软件,Pycharm对比vscode,目前仍然有以下优势:

  1. 代码版本管理。Vscode虽然同样支持了Git,但到今天为止,它并没有一个好的基于GUI的三路归并工具,这使得merge代码的效率十分低下。
  2. DataView。Pycharm原生支持多种数据格式查看,比如DataFrame。我没有寻找过Vscode的插件,但通过Vscode的原生能力来查看象DataFrame这样类似表格的数据,还是比较吃力的。
  3. 很多功能开箱即用,无须配置。而在VsCode中某项功能即使可用,也需要安装扩展才能支持。

VsCode具有的优势: 1. 启动速度更快。 2. 调试模式下查看变量值更方便,直接通过REPL窗口,以类似命令行的方式进行求值。与之对比的是,Pycharm中需要打开一个对话框,略显慢一点。

在远程调试的支持上,Pycharm的Community Edition版本不支持(即使是WSL也不支持),而VsCode是可以很好地支持WSL的。所以如果是与Pycharm CE版本相比较,那VsCode是可以胜出这一局的(但仍然在代码合并上输掉一局)。

我的推荐是两款IDE都要安装。Python开发使用Pycharm,这个工具相信你会越用越喜欢。而Vscode我用来写文档(rst, markdown),日志和管理任务,因为VsCode的启动速度够快,相关插件也够多。

Python及虚拟环境的安装

任何一个程序员都不可能从头到脚去自己开发程序的每一个模块。必然地我们要借鉴和使用他人的开发成果,同时也希望我们的开发成果被更多的人使用。这样不可避免地造成一个问题: 如果我们的程序中使用了他人开发的模块,并且使用了它的早期版本;而另一个程序也使用了同样的模块,但使用的是晚期版本,这时候两个程序应该如何共存?

这个问题的出现至少可以追溯的Windows的早期。在Windows中,这些共享库以DLL(动态链接库)的形态出现。由于不同的版本相互冲突,导致出现了被我们称为DLL地狱的现象出现。为了解决这个问题,早开始出现了通过虚拟机进行运行环境隔离的解决方案,随后又进化到基于docker进行运行环境隔离的方案。这些都是操作系统层面级的解决方案。

Python是我知道的最早支持虚拟环境的开发语言。开发者可以为自己的应用程序构建单独的虚拟环境,在这个环境里,所有的第三方模块都只为这一个应用程序服务,因此它们的版本可以固定下来。在一台机器中,可以同时存在多个虚拟环境,也可以同时运行基于多个虚拟环境的多个应用程序。

Python中有两个构建虚拟环境的方式,即Virtual Env和Conda。在这一期中,我们主要讲基于Conda构建虚拟环境。在持续集成那一部分,则会提到VirtualEnv。这两种方式都被Pycharm和WSL支持。

安装conda

多数从事数据科学的人从安装完整的anaconda开始。这一般会占用你硬盘上好几个G的初始空间,并且随着虚拟环境的创建持续增长。对从事工程开发的人来说,则可以从miniconda开始。两者的区别是,前者包含了很多科学计算用的工程包,比如numpy, scipy, sklearn等等,还有一个名为spyder的集成开发工具。

Miniconda的下载地址在这里。一般是50M上下,包含了一个基本的Python解释器。Miniconda的python版本并不重要,因为后面我们都将为虚拟环境安装特定版本的Python。

我们将Miniconda安装到WSL中,因此,我们应该运行下面的命令:

sh <(curl -s https://repo.anaconda.com/miniconda/Miniconda3-latest-Linux-x86_64.sh)
           

如果WSL上没有安装curl,请先通过

suod apt install curl

来安装。

从anaconda官网上下载miniconda可能较慢,也可以先通过下载工具将上述文件下载下来,再传入到WSL中去。

修改源

conda和pip都是重要的软件分发方式,pip专门用于Python程序分发,conda则还包含了其它软件。无论使用哪一种,在国内使用时,与apt一样,也需要更改源。

我们首先用pip下载安装一个辅助包,cfg4py,然后通过它来配置Conda和pip:

pip install cfg4py
           

对于初学者,需要了解一下pip。pip是一个python模块;我们一般通过python -m xxx来运行xxx模块,比如启动一个简单的http服务器,我们可以运行:

python -m http.server
           

一些Python模块支持console script,使得它们可以象linux命令一样被调用(这也是Python与Linux融合的一个思想),比如pip。既然pip是一个Python模块,那么它就对运行它的Python有版本要求,所以如果你遇到无法运行pip的情况,就需要检查python的版本。我们也可以通过下面的方式来运行pip:

python -m pip install xxx
           

如果出错,也许这将报出更有意义的诊断信息。

现在,我们使用cfg4py来更改Conda和Pip的源:

cfg4py hint conda --usage
           

我们将得到以下输出:

Usage: execute command:
 conda config --add channels %url
 or edit your ~/.condarc to add the following:

- tsinghua:
    channels:
    - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/main/
    - https://mirrors.tuna.tsinghua.edu.cn/anaconda/pkgs/free/
    - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/conda-forge/
    - https://mirrors.tuna.tsinghua.edu.cn/anaconda/cloud/pytorch/
    ssl_verify: true
- ustc:
    channels:
    - https://mirrors.ustc.edu.cn/anaconda/pkgs/main/
    - https://mirrors.ustc.edu.cn/anaconda/pkgs/free/
    - https://mirrors.ustc.edu.cn/anaconda/cloud/conda-forge/
    ssl_verify: true
           

命令给出了修改conda源的两种方式和具体的源地址,一组是清华源,一组是中科大源。我们再来看看如何修改pip源:

cfg4py hint pip --usage
           

输出如下:

Usage: add the following to ~/.config/pip/pip/conf:
 [global]
 index-url = https://mirrors.aliyun.com/pypi/simple/
 [install]
 trusted-host=mirrors.aliyun.com
or execute command:

- tsinghua: pip config set global.index-url https://pypi.tuna.tsinghua.edu.cn/simple
- aliyun: pip config set global.index-url https://mirrors.aliyun.com/pypi/simple/
- tencent: pip config set global.index-url http://mirrors.cloud.tencent.com/pypi/simple
- douban: pip config set global.index-url http://pypi.douban.com/simple/
           

创建虚拟环境

我们使用conda来创建虚拟环境:

conda create -n your_env_name python=3.8
           

上面的命令将在你的miniconda安装目录的envs目录下,创建一个名为your_env_name的文件夹,并将python 3.8及相关文件安装到这个目录下。安装完成时,conda会提示你使用以下命令:

conda activate your_env_name  #激活python虚拟环境
conda deactivate              #退出当前的虚拟环境
           

当虚拟环境激活时,命令提示符一般会显示为虚拟环境名字;此时运行python,会启动当前虚拟环境下安装的Python版本,而此后加载的Python库,都来自于该虚拟环境下通过conda或者pip命令安装的库。

pip并不是conda的一部分,为何能知道将python库安装到哪个虚拟环境中去呢?原因是,启动的Python来自于当前虚拟环境,因此它有所有的信息,可以将Python库安装到正确的位置。

关于conda还有一些常见的命令,这里一并提一下: 1. conda env list, 显示本机上所有的虚拟环境 2. conda env remove, 移除一个虚拟环境 3. conda create -n your_virutal_env --clone your_another_env,从另一个已存在的虚拟环境中创建。Conda没有改名的操作,所以如果要给一个虚拟环境改名,我们可以先clone,再删除掉旧的虚拟环境。 4. conda install, 安装软件到当前环境 5. conda search, 查找是否存在某个软件

在上面的创建命令中,除了象上面那样使用CPython发行版外,还可以使用特殊的Python版本,比如Intel发行版:

conda update conda
conda config --add channels intel
conda create -n idp intelpython3_core python=3
           

使用Intel版的Python的一个原因是,它可能提供了更强性能的数学计算功能。具体可以看这里。这对从事数据分析为主的程序员还是比较有帮助的。

Jupyter Notebook和JupyterLab

Jupyter Notebook是一个基于网页的、可以按单元格分步运行的Python开发环境,主要用于探索式编程。如果您主要从事的工作是数据分析,应该优先安装使用Jupyter Notebook:在Jupyter Notebook中,您可以一边写文档,同时一边写代码,代码运行结果如果是一张图的话,也可以直接显示在网页中。现在Jupyter Notebook已经支持可视化调试(通过xeus-python插件)、代码提示和自动完成。但是在code jump,refactoring和代码管理上还很欠缺。这就限制了它在工程化方面的发展。来自于FastAI的科学家对此作了一些改进,试图将其打造成一个IDE,提供了代码管理、Unittest等功能,但目前来看,仍然无法替代传统的IDE来进行工程化的编程。关于他们的研究,感兴趣的可以看这里。

Jupyter Lab被认为是Jupyter Notebook的下一代版本。在工作区的划分上,提供了类似于IDE的多个功能区,支持工作区文件列表等, 同时运行的多个标签页可以彼此调用,因此比Notebook增强了工程化能力。不过基于Web的IDE目前看也都没有特别亮眼的表现,Jupyter Lab也概莫能外。

总结

本期文章给出了在Windows上从事Python开发的常用环境搭建方法。与其它文章不同的是,本文更注重介绍技术背后的背景,以便知其然,更知其所以然。

纯的Windows开发已经不再受人喜欢。因为就连微软自身也在拥抱Linux,拥抱开源。所以我们的开发环境搭建在Win 10 + WSL之上,可以同时享受到两种操作系统的便利。使用WSL作为Python程序的调试和运行环境,因为多数软件和库对Linux支持得更好,优先级更高。

尽管VsCode很优秀,但没有理由不使用Pycharm,尤其是新人,不应该把时间花在自己一时无法一探究竟的各种插件的安装配置上。不使用Pycharm的根本原因只有一个,就是License问题。

从事数据科学的工程师可以使用Jupyter Notebook或者Jupyter Lab。

为你的每一个项目创建一个单独的conda 虚拟环境,以避免各种库之间的版本冲突。

更多阅读

继续阅读