在跟我学AI量化交易(1) - 获取行情数据中提到,这部教程的开发语言是Python,因此不可避免地将涉及Python编程知识。这里发表一些相关的基础知识,作为辅助入门材料。

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

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

目标

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

1. 使用Windows图形界面来运行客户端程序,包括集成开发环境(Pycharm)和文档写作工具。

1. 使用Linux来运行和调试代码。许多开源软件和库对Linux支持得更好。比如在2017年,在Windows上安装Redis还是一件比较麻烦的事。开发nodejs的程序员也常常发现,在Linux下很多npm包有着丝滑般的安装体验,而在Windows上则会是一路跌撞撞。这也是Windows现在大力拥抱Linux的原因之一。在这一部分,我们将介绍WSL。

1. Python虚拟环境的构建

Windows和相关开发软件的选择

无论如何,在2020年你都应该停止使用其它版本的Windows,而只使用最新的Windows 10系统。原因之一是,Windows 10现在提供了最好的Linux发行版,更为奇妙的是,这两个系统现在可以同时运行,甚至无需切换;两套系统共存而带来的性能代价极小,远远小于其它方案,诸如虚拟机或者docker。

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

现在是时候推荐WSL - Windows Subsystem for Linux了。它现在已经很棒。

WSL - 运行在Windows上的Linux

当前有两个版本可用,wsl v1和wsl v2, 我个人更推荐使用wsl v1。WSL v2的体验更象虚拟机,因此与windows集成性反而更差一些。当然,我得出这个结论是在2020年的5月,也许近半年之后,事情已经大有不同。但无论如何,在本文中,我推荐的是WSL v1.0。对于Python开发是没有任何问题的;如果用于nodejs或者前端开发,可能要担心性能问题(因为wsl v1的文件系统性能不太好,而js开发文件特别多,小文件又多)。

安装WSL

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




linux 无法切换python版本 linux切换python环境_linux 无法切换python版本


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


linux 无法切换python版本 linux切换python环境_windows python 无缝切换_02


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


linux 无法切换python版本 linux切换python环境_linux 无法切换python版本_03


此外还要对ssh服务进行设置。我们设置ssh服务的目标是为了开机自启wsl子系统(无窗口模式),这样我们可以随时以ssh方式连接进去,就好像我们有了一台Linux服务器一样。也许你安装的版本已经直接设置好了ssh server,所以这里我们略过。如果没有,具体设置可参考Ubuntu的ssh设置。

WSL并不会随windows一起启动。这里我们介绍一种方法,使得当Windows启动时,wsl也随之启动,并可以通过你喜欢的ssh客户端来连接。

这里使用的方案是来自于https://github.com/troytse/wsl-autostart。具体操作可见wsl-autostart/README_zh.md at master · troytse/wsl-autostart · GitHub。

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

安装Windows Terminal

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

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

WSL与Host机器共享文件

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

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

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

使用哪一个IDE?

目前"唯二"的选择,就是Pycharm和vscode。如果你已经熟悉Vscode,推荐使用vscode;否则推荐使用Pycharm。当然,如果机器配置略差,也建议使用vscode。使用vscode的另一个好处是,它与wsl有很好的集成性,直接支持将源代码放置在wsl之中,或者远程的linux机器之上进行开发,就好像这些文件仍然在本地一样。Pycharm专业版尽管有支持这些场景,但它使用的远程路径映射方案并不如vscode那么好用。

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

  1. 代码版本管理。Vscode虽然同样支持了Git,但到今天为止,它并没有一个好的基于GUI的三路归并工具,这使得merge代码的效率比较低下。但另一方面,vscode的扩展gitlens却十分好用。Pycharm虽然通过local history和git diff也支持同样的功能,但在界面接口设计上,感觉不如vscode。
  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支持。

安装conda

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

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

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


linux 无法切换python版本 linux切换python环境_linux 无法切换python版本_04


如果WSL上没有安装curl,请先通过suod apt install curl来安装。

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

修改源

在继续创建虚拟开发环境之前,我们先要配置一下conda或者pip。这两个工具都在中心服务器及其镜像上维护了开源库的目录,并为他们提供分发。其中,pip专门用于Python程序分发,conda则还包含了其它软件。无论使用哪一种,在国内使用时,与apt一样,都需要更改源,否则安装速度会很慢,甚至无法安装成功。

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

python -m http.server

一些Python模块支持console script,使得它们可以像linux命令一样被调用(这也是Python与Linux融合的一个思想),比如pip。这就是为什么你可以直接运行pip命令的原因,它实际上是python的脚本。

既然pip是一个Python模块,那么它就对运行它的Python有版本要求,所以如果你遇到无法运行pip的情况,就需要检查python的版本。我们也可以通过下面的方式来运行pip:

python -m pip install xxx

这种方式下,python就是你的系统路径下能找到的那个版本。如果出错,也许这将报出更有意义的诊断信息。

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


linux 无法切换python版本 linux切换python环境_windows python 无缝切换_05


我们将得到以下输出:


linux 无法切换python版本 linux切换python环境_Windows_06


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


linux 无法切换python版本 linux切换python环境_Windows_07


输出如下:


linux 无法切换python版本 linux切换python环境_linux 无法切换python版本_08


这里使用了cfg4py这个开源库。它除了可以帮助我们更改conda,pip的配置之外,还提供了诸如redis, mysql, postgres等连接串配置。cfg4py本身是一个python的配置模块,主要为你的Python程序提供多层次、多环境配置。这个库也是本文作者开发的,这里说明一下。 ## 创建虚拟环境 {#创建虚拟环境 } 我们使用conda来创建虚拟环境:


linux 无法切换python版本 linux切换python环境_Python_09


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


linux 无法切换python版本 linux切换python环境_windows python 无缝切换_10


当虚拟环境激活时,命令提示符一般会显示为虚拟环境名字;此时运行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发行版:


linux 无法切换python版本 linux切换python环境_Python_11


使用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 虚拟环境,以避免各种库之间的版本冲突。