高中开始听说Python,大概大三到大四之间尝试动手写。毕业后成为了一个Android码农,Python不是主力语言,零零星星写过一些顺手的小东西,而且主要在公司。
家里电脑本来就用得不多,还经历了多次重装。旧电脑全格了,从Win+Linux双系统变成了Linux专用;新电脑经历了升Win10之后几次系统崩溃C盘重置,后来又从32改64。
D盘的东西虽然还在,但各种配置乱得不行。这会要写Python,各种配置都要重新弄。反正都好几年前装的,干脆重新安装配置一遍。
不看不知道,果然很多东西都变了。
结论
正文写得很零碎,这里给个结论:
- 如果你有同时用2、3的需求,分别安装2 和 3的最新版本(2.5这种古董还是别碰,焦头烂额),然后通过在代码开头写Shebang指定用哪个解析器执行。
- 包管理用pip。作为Python包管理的事实标准,流行的包都会注册到pip。你知道包名之后,要用不过是一句
pip install 包名
。 - 如果更进一步,你的不同项目之间要依赖不同版本的包,用virtualenv 来管理你的包。
- 虽然Python用Notepad++ 写然后执行完全没有问题,但即使老司机也有大意的时候,新手更应该培养良好的编程规范,PyCharm 是个不错的选择,特别是Community版本免费,对于绝大多数人而言都是够用的了。
四年前写过一篇文章记录当时Win上配置Python2+3,现在看做法各种过时。譬如说2011年才发起的pip在当年我还不知道,现在已经成为了包管理器的事实标准。
pip
四年间不怎么关注Python的消息,居然也大概知道pip。然后查了一下目前主流的包管理器的对比,发现《Python 包管理工具解惑》 写得比较好。
不看不知道,包管理相关的工具已经有这么多!
- distutils
- setuptools
- distribute
- disutils2
- distlib
- pip
结论是pip已经成为了事实标准,所以默认情况下用pip,遇到特殊情况再考虑别的。详情看那篇文章,不再展开。(考虑到作者换博客等因素,文章链接可能失效,到时只好用标题搜搜看。)
Ubuntu
同样的事情我在Ubuntu上也折腾过一遍。Python对Linux友好太多,很简单的就弄完了。简单过一遍,用来跟Windows对照。(当然,简单还有一部分原因是,我没在Ubuntu装2.5)
没记错的话,Ubuntu自带Python2.7,所以我只要装Python3,然后分别装pip就好
|
|
这之后
|
|
Ubuntu 自带的pip版本太旧,要升级一下
warning : 如果是在Windows升级,请使用 python -m pip
,原因详见 《升级 pip 时的一个坑》
|
|
这里就让我疑惑了,为什么唯独pip
没有生效呢?我把PATH输出来
|
|
确实是local的在前面。而且我看了这三个名字的script,内容都是一样的。不过我还没搞清楚原因,第二天开机,就都变成8.1.2了。原因大概能猜到一二,但除非重头折腾,已经无法验证了。如果有大牛知道详细原因,欢迎留言告知。
看到这里,相信大家已经懂得,分别用 python
V.S. python3
,以及 pip
或 pip2
V.S. pip3
就可以调用对应的版本了。
果安装了更多的版本,譬如不止一个Python2,有2.5 和 2.7,那么还可以更具体地区分pip,那就是直接 pip-2.5
VS pip2.7
。(pip某个版本以前,规则是pip-<ver>
,之后变成了pip<ver>
。支持2.5的都是老版本,所以带有横杠。详情可以查看 /usr/local/bin
里都有哪些文件。)
这是在bash执行 python xx.py
的情况,那如果是直接给执行权限当脚本跑呢? 写shebang!在脚本开头写
|
|
或
|
|
Windows
双 Python for win
Windows 这边,我选择的组合是 Python 2.5 + Python 3.4。
选择2.5的原因是,虽然2.5 和 2.6/2.7 都是 2.x , 但只有 ≤2.5 才是纯粹的2.x, 2.6/2.7 其实是已经引入了 3.x 语法的过渡版本。
2.6/2.7 的代码固然不能在2.5上跑,而2.5 on 2.6/2.7 虽然大多跑得过,也往往存在某些不可预料的结果。(网上很容易搜到例子)
我主要还是写3.x的,所以两个系统都装了3.4,但是难免有需要跑一些陈年代码的时候,考虑到Ubuntu自带2.7,Windows就装2.5了。
都安装上是没有难度的,问题是运行。
这涉及到3种运行情况:
- 双击执行
*.py
文件(CLI,也就是纯CMD) - 双击执行
*.py
文件(GUI,也就是通过PyQt一类库实现了界面的) - 在CMD窗口里执行,同样分以上两种情况
两个版本都刚安装完的时候,默认的情况应该是:
1、2 都是哪个在后面安装就调用哪个。因为在Windows,双击执行靠的是文件类型关联,如果安装的时候都有执行文件关联的话(我记得默认这个是有选上的),那么后面的会覆盖前面的。
换言之,假设我主要用 3.x ,那么先装 2.x 再装 3.x ,那么双击运行的都是 3.x ,2.x 就调用不了了。
第3种情况,命令行里执行 python xxx.py
, 如果你没有去系统的Path环境变量添加这两个Python的话,实际上系统会找不到 python。然后如果你往Path里 把两个的 bin 目录都加进去,由于搜索是从前往后寻找,命中就结束,所以是哪个在Path里靠前执行哪个,靠后不起作用。
随时指定版本
那么现在的问题就是,如何在不重新安装,以及不修改Path的值的情况下,随时指定Python的版本。(四年前我的方案是,新建一个环境变量放进Path,然后通过批处理修改该变量的指向来解决情况3,没有解决1、2。当然四年前也还没有PEP397)
PEP397 给出了官方解决方案。
详细内容大家可以点进去自己看。核心内容是,安装3.3 以上版本时(这样才包含PEP397),会在 C:\Windows\
下放一个启动器 py.exe
,通过启动器运行,可以用参数指定启动的版本。
命令行参数指定
|
|
或
|
|
当然,如果你装的版本更多,你可以指定得更详细,譬如
|
|
但是如果指定的版本不存在,那么就会报错
|
|
本质上,py.exe
只是接收了第一个参数,然后查找参数对应的版本的 python.exe
,然后把剩下的参数转给它。同样在 C:\Windows\
下另外还有一个 pyw.exe
对应 pythonw.exe
。
不过每次都要指定也太烦了,每次运行前都要先想想这是哪个版本的代码,这个其实不是在写的时候已经决定好了吗?跟Linux类似地,还是写shebang。
Shebang 指定
个人认为Windows 下面的,严格来说应该不算shebang,只是模仿了这种形式。毕竟在Linux下,shebang所以是写给shell解析的,而这里其实是给 py.exe 解析的。
|
|
或
|
|
如果我们写的是跨平台的代码,Windows和Linux都要跑呢?这种伪shebang 在 Linux并不被接受。
|
|
很简单,两边都写Linux风的shebang就好了。即使Windows下并不存在 /usr/bin/python3
这么个东西,一样可以运行。(所以才说它是个伪shebang,其实只是给py 解析的参数而已)
|
|
双击执行
双击执行当然没办法给 -2
这样的参数,所以要在代码里面写上shebang。
同时为了让它生效,必须确认 .py
文件关联的是 py.exe
,而不是某个版本的 python.exe
。
对着某个 .py
文件,右键查看属性 -> 打开方式,确认一下。
如果最后安装的是Python3.3 以上的版本,貌似会自动给关联 py.exe
。不过不是也没关系,自己改过来就好。
类似的,如果是GUI程序,可以把后缀改为 .pyw
,同时关联 pyw.exe
。
嗯……其实区别只是,pyw.exe
会将调用转给 pythonw.exe
,跟 python.exe
相比,运行时不会显示命令行黑窗 (因为有GUI给你看嘛,还看什么小黑窗)。调试的时候,可以临时把文件名改为 .py
看输出。
不过,个人更推荐使用 logging
输出详细的调试信息。
pip for win
要庆幸的是,Python3.4 for win 已经自带了 pip。所以我只要为2.5安装即可。
实测发现,2.5实在太旧了(2.5的时代还没有pip吧),用pip自动安装2.5下的包,基本都会出错(其实是选了声明支持2.x 的包,结果里面有2.6以上的语法,会出错),所以给2.5安装pip实用价值不大。 我装2.5 本来就是为可能的测试预留的,没有必要花大力气,真有需要也可以setuptools 安装,所以最后放弃了折腾。
如果是Windows下的2.7 安装pip:
- 安装对应版本的setuptools
setuptools ,留意不同版本的安装方法略有差别 - pip ,下载对应的pip包并解压,在解压后的目录执行
> py -2 setup.py install
这之后,就可以
|
|
或
|
|
不方便的地方是,没有 pip2 / pip3 ……
其实是有的,不过要先将各个版本安装目录下的 Scripts
目录加入Path 环境变量。
加入之后,pip
指向的版本,取决于你将哪个目录放在前(因为两边都有pip,看哪个先命中),然后具体指定版本,就要看Scripts下都有那些文件了。3.x 下应该 pip3
和 pip3.x
都有,但是2.5 下 只有 pip-2.5
没有 pip2
(其实跟上面Linux下的情况基本一致)。
Virtualenv
暂时对于多版本环境需要不是特别大,之后用到再详细写。
以下是针对2.5的操作,包含不必要的试错,主要是无用功,留作供我日后参考。
跟2.7类似,也是两步
安装setuptools。因为支持2.5的setuptools是1.x版本,不能用最新的,而要用这个链接 Setuptools 1.x
下载最新的支持Python2 的pip包,当前这个时刻是8.1.2,解压,在解压后的目录执行
> py -2 setup.py install
结果报语法错误。仔细一看,原来 8.1.2 最老只支持 2.6,重新找,又下载了 支持 2.5 的 1.4.1。结果依然有语法错误。但是这次支持版本信息没错啊,只好自己去看报错信息。
看代码的结论是,pip1.4.1 声称支持 Python2.5,它还是引入了Python2.6 为 Python3 准备的过渡语法 b''
,以至于一运行就有错误。实际上支持2.5的最新pip版本是 pip1.3.1。
折腾至此,实际上已经费了好多时间和精力,总算把 pip1.3.1 给 2.5 安上了。那么我就来安装一些包看看。
|
|
2.5 默认没有SSL包,而pip需要用SSL下载包……
好,我先安装SSL总可以吧
|
|
变成了先有鸡还是现有蛋的死循环了…
那我关掉加密传输不要SSL总可以了吧…
|
|
额,又是引进了 2.6 的语法,这次是关键字 with
…
看来 pip 对 2.5 并不友好。pip 的本意是包管理的自动化。如此折腾就违反初衷了。反正 2.5 不是用来开发用的,偶尔需要什么包,手动安装一下也不费什么事,所以就此打住,不折腾pip了。
本文为本人原创,采用知识共享 “署名-非商业性使用-相同方式共享” 4.0 (CC BY-NC-SA 4.0)”许可协议进行许可。
本作品可自由复制、传播及基于本作品进行演绎创作。如有以上需要,请留言告知,在文章开头明显位置加上署名(Jayce Chant)、原链接及许可协议信息,并明确指出修改(如有),不得用于商业用途。谢谢合作。
详情请点击查看协议具体内容。