Python二三事 - 接触Python(x,y)

注释:本文原来转自博客大巴的一篇文章,向原作者致谢!我也做了相应的修改,更加完善对于Pythonx,y的介绍

Python 二三事

  面向初学者介绍Python相关的一些工具,以及可能遇到的常见问题。

 

更新1st 2011.1.15

更新2nd 2012.3.4

引言

在这里我假设你已经看完了一篇Python教程,基本熟悉了Python的结构和语法,在命令行下的Python互动环境中尝试过大部分Python的语句,觉得Python是个不错的语言准备继续下去。那么本篇文章会就Python实际运用中相关工具的选择,包括IDE,调试套件,第三方库管理工具这些进行介绍。另外还会对某些中文环境下容易遇到的问题,例如unicode编码解码的问题进行说明。本文主要是针对 Windows 环境下的 Python 开发进行说明。文章的目的是为了分享些我觉得很有用的经验和例子,若发现文中有疏漏之处请务必联系我。谢谢。


Python 语言介绍

Python 是一个近些年在开始流行起来的计算机编程语言。根据Python官网上的简介,Python主要特性包括跨平台,免费,简单且容易维护。就我个人理解来说,Python是一门适合大部分人的语言,因为各种类型的第三方库都有,所以像简单桌面程序,动态网站开发,图像处理,表格处理,甚至自动发帖机这些小应用在简单的学习后,不需要很深厚的编程经验的人应该都能自己做出来。

一些流行的Python教程

 

Dive into Python 面向有一定编程基础的同学。另外还有Dive into Python 3,针对Python3的教程。


 

Learn Python The Hard Way,书中主要是通过各种练习来进行学习,面向完全没有编程经验的同学。


 

Invent Your Own Computer Game With Python,让你一上手就做个游戏出来的教程,厉害吧。


 

The Python Tutorial,官方文档中的教程,正统而完整。

 

How to think like a scientist:learn with Python,强烈推荐初学Python和编程的同学,MIT的教材,目前也被用于南科大的CS课程中

 

Hello,World     教小孩子学编程的好书,使用的是Python作为编程语言


 

如果你还没有开始接触 Python ,或者觉得还不够熟悉,那么不妨找一份你觉得看得下去的教程开始学习吧。就我个人经验来说,Python 是我到目前为止觉得学的最划得来的一门语言,也是日常用的最多的一门,而事实上你并不需要了解完全了解 Python 就能在开始使用它。

Python 版本选择,其他发行版

纠结于Python 2 与 3?

Python 2 和 3 系列的选择可能是比较让人烦躁的事情。其实区别很简单:Python 3.x 各个方面都更好,但语法与 Python 2.x 很大部分不兼容。Python 2.x 已经停止继续开发。但是目前很多第三方库仍然不支持 Python 3 , 文章后面介绍的很多工具譬如 ipython 目前也是仅支持 Python 2.7 的。

我建议现在选择 Python 2.7.2 ,因为目前大部分第三方库和工具对2.7都有简单的安装包,不需要自己做太多处理,关于2.6还是2.7,推荐2.7,比2.6内置了一些包,不需要再安装了。

 发行版

目前在 Windows 下除了官方提供的安装版外,还有:

ActivePython ,这个与官方版本的区别在于提供了额外的库和文档,并且自动设置了PATH环境变量(后文会详细提到)

Python(x,y),这个是我一直用并且推荐给别人用的版本。从名字就能看出来这个发行版附带了科学计算方面的很多常用库,另外还有大量常用库比如用于桌面软件界面制作的 PyQt, 还有文档处理,exe文件生成等常用库。另外的还有大量的工具如IDE,制图制表工具,加强的互动shell之类。很多下文提到的软件在此发行版中都有附带。其他方面,Python(x, y)还附带了手工整理出的所有库的离线文档,每个小版本升级都提供单独的补丁。总的来说是很用心维护的一个发行版,十分建议安装这个版本。

开发相关工具

在真正着手开发之前,你应该在下载一份离线的文档。在这个页面下载一份 HTML 格式的,解压出来其中 index.html 就是文档主页面。页面左边的 Quick Search 是离线也可以使用的,有对函数功能有疑惑或者要查询模块的时候就能在这里查看。


选择 PyDev 作为 IDE

Python 集成开发环境的选择好像一直以来也是一个很难抉择的问题。在尝试过很多个工具后我发现基于 Eclipse 的 PyDev 绝对是功能最为完整的一个 IDE 。除了断点调试之外,PyDev 的代码自动补全可能是现在这类 IDE 中最强力的。

如果你安装了 Python(x, y) 的话,PyDev 就已经在你的机器上了。如果没有的话请按照这篇文章来进行安装。

设置上有一些需要注意的地方。首先在打开 PyDev ,打开菜单中 Window -> Preferences,在弹出对话框中左边找到 PyDev -> Editor -> Code Completion。这里可以设置代码自动补全的相关信息。可以降低 Autocompletion delay 来更早的提示代码,并且将 Request completion on 系列尽可能勾上,让 PyDev尽可多的提示代码。之后再找到 Interpreter Python选项卡,这里可以设置所谓 Forced Buildins,可以强制引入某些第三方库从而完成代码补全。就我的经验来看大部分第三方库在这样设置后都能进行基本的补全。具体的做如图中,选择到对应的选项卡,点击 New,并输入你需要的模块名字即可。

Forced Buldins设置

设置后总体效果绝对是同类IDE中比较好的:

Eclipse 补全效果


IPython 替代 Python Shell

在学习 Python 的时候应该都接触过 Python 的 Shell,能够输入 Python 语句并且立即返回结果。而 IPython就是一个豪华加强版的 Python Shell。如果你安装了 Python(x, y) 的话,那 IPython 已经在你的机器上了。如果没有的话那么请在这里下载 Windows Installer 进行安装。在安装这个之后还需要安装 pyreadline 让 IPython 开启高亮和自动补全功能。

之后你在命令行下需要 python 的时候改为输入 ipython就能使用它了。开启 IPython 看看,首先感觉的不同应该是这个是有颜色的。我们来看看它提供的一些基础而实用的功能吧。首先是自动补全,一种是简单的关键字补全,另外一种是对象的方法和属性补全。作为例子,我们先引入 sys模块,之后再输入 sys.(注意有个点),此时按下 tab 键,IPython 会列出所有 sys 模块下的方法和属性。因为是在互动模式下进行的,此时的 Python 语句实实在在的被执行了,所以对普通 object 的补全也是很完好的。

IPython

接着上面的例子,我们输入 sys?,这样会显示出 sys模块的 docstring及相关信息。很多时候这个也是很方便的功能。

IPython 另外还有很多方便的功能,可以自己参阅文档来发掘。这里另外介绍一个很神奇的功能。如果你的程序是由命令行开始执行的,即在命令行下输入
python foo.py(大部分 Python 程序都是),那么你还可以利用 IPython 在你的程序任意地方进行断点调试!在你程序中任意地方,加入如下语句:


from IPython.Shell import IPShellEmbed IPShellEmbed([])()

再和平常一样运行你的程序,你会发现在程序运行到插入语句的地方时,会转到 IPython 环境下。你可以试试运行些指令,就会发现此刻 IPython 的环境就是在程序的那个位置。你可以逐个浏览当前状态下的各个变量,调用各种函数,输出你感兴趣的值来帮助调试。之后你可以照常退出 IPython,然后程序会继续运行下去,自然地你在当时 IPython 下执行的语句也会对程序接下来的运行造成影响。

 

这个方法我是在这里看到的。想象一下,这样做就像让高速运转的程序暂停下来,你再对运行中的程序进行检查和修改,之后再让他继续运行下去。这里举一个例子,比如编写网页 bot ,你在每取回一个页面后你都得看看它的内容,再尝试如何处理他获得下一个页面的地址。运用这个技巧,你可以在取回页面后让程序中断,再那里实验各种处理方法,在找到正确的处理方式后写回到你的代码中,再进行下一步。这种工作流程只有像 Python 这种动态语言才可以做到。

ipython与Linux的完美结合

  当然Ipython最NB的地方在于和Linux系统的无缝连接,简单介绍一下在Ubuntu下的使用,首先需要安装Ipython:

  root@3414-mainsrv:~# sudo apt-get install ipython

  接着就可以在终端下使用了,有个一个称为是magic的函数:

In [1]: magic

IPython's 'magic' functions
===========================

The magic function system provides a series of functions which allow you to
control the behavior of IPython itself, plus a lot of system-type
features. All these functions are prefixed with a % character, but parameters
are given without parentheses or quotes.

NOTE: If you have 'automagic' enabled (via the command line option or with the
%automagic function), you don't need to type in the % explicitly. By default,
IPython ships with automagic on, so you should only rarely need the % escape.

Example: typing '%cd mydir' (without the quotes) changes you working directory
to 'mydir', if it exists.

You can define your own magic functions to extend the system. See the supplied
ipythonrc and example-magic.py files for details (in your ipython
configuration directory, typically $HOME/.ipython/).

You can also define your own aliased names for magic functions. In your
ipythonrc file, placing a line like:

execute __IPYTHON__.magic_pf = __IPYTHON__.magic_profile

will define %pf as a new name for %profile.

You can also call magics in code using the ipmagic() function, which IPython
automatically adds to the builtin namespace. Type 'ipmagic?' for details.

For a list of the available magic functions, use %lsmagic. For a description
of any of them, type %magic_name?, e.g. '%cd?'.

 

  我们来举个例子把,例如有一个称为是bg的魔法函数,它的作用是用来在后台进行计算,我们需要计算一下2的10次方,只需要按下面输入即可交给bg函数把计算丢到后台去计算而不影响你的继续操作,你只要记得job的序号是1,需要结果时,只要把jobs[1]中的result输出就可以了

In [10]: bg pow(2,10)
Starting job # 1 in a separate thread.

In [11]: print jobs[1].result
1024

  此外,使用rehash函数,你完成可以把ipython当做是shell使用,你可以使用任何命令,例如:

In [15]: ps aux|grep DarwinStreamingSrvr
root 17496 0.0 0.0 2040 508 pts/0 S+ 10:12 0:00 sh -c ps aux|grep DarwinStreamingSrvr
root 17498 0.0 0.0 7368 852 pts/0 S+ 10:12 0:00 grep DarwinStreamingSrvr

pip 管理第三方库

Python 的一大优势就是有极为大量的第三方库,包括各个方面的引用。然而安装第三方库对没有掌握方法的同学来说会变得很让人烦恼。事实上 Python 第三方库的安装和管理有着一个一个唯一正确的做法,这个做法要求你什么其他的都不用干,只要输入你要安装库的名字就可以了。

setuptools 也包在 Python(x, y) 当中。如果没有的话,要首先先安装 setuptools ,这个其实就是一个安装第三方库的软件。选择对应版本的 Windows Installer 进行下载和安装后,打开一个命令行窗口,输入:


easy_install pip

如果提示找不到程序,那么说明你当前没有设定好环境变量。安装官方提供的 Python 安装包的话肯定会有这个问题,而且很可能暂时不会修正,这就是牛逼程序员的倔强。具体做法是 右键我的电脑 - 属性 - 高级系统设置 - 环境变量 - 将 C:\python2*\Scripts加入到 PATH 那一组当中。这样做的效果就是在任何地方的命令行下输入命令,那么系统会额外查找我们设定的那个目录中的内容。之后再执行上面的命令,装好了以后我们就要弃用 setuptools,转投 pip。要安装任何一个库,你只要找到他的名字(不需要版本号),用 pip 安装即可。譬如安装 django,那么输入如下命令即可:


pip install django

其实之前 easy_install跟 pip效用是类似的,都是在官方的第三方库索引 PyPI 查询信息并进行下载和安装。pip 的优势在于支持更高级的功能,譬如虚拟环境,安装失败不会残留破损的库,更重要的是 pip 还可以进行卸载。输入下面命令就能卸载一个之前由 pip 进行安装的库。继续上面的例子,现在要卸载 django:


pip uninstall django

这是 setuptools 所缺失的功能。需要额外说明的是大部分纯 Python 的库都能用这个方法在 Windows 下装上,但是需要编译 C 语言模块的一般都不太可能成功。遇到这种情况,在相应的库德站点上找找有没有对应的 Windows 安装包。


Winpdb

如果你使用的 PyDev 的话那么用其自带的断点调试应该就可以了。Winpdb则是为用其他简单编辑器进行 Python 开发的用户提供一个熟悉的调试环境。Winpdb不出意料的也在 Python(x, y)当中。所以如果装上 Python(x, y) 你可以不断发掘里面附带的优秀工具。使用方法很简单,假设程序名为 foo.py,那么在命令行中输入:


winpdb foo.py

之后会弹出窗口,也就是一个大家都熟悉的 debug 图形界面。需要注意的是这里需要点击想要设置断点的行,点击 F9 设置断点,然后该行底色会变为红色,如下图所示。

Winpdb

编码问题

作为中文用户,初学 Python 最容易碰到的问题估计就是编码问题了。明明英文的都可以用到中文的时候就要出问题,而且出错信息难以理解,想要解决问题又不知道从何开始。幸运的是编码问题通过预防性的措施是很好避免的。下面从几个方面来讲讲 Python 中处理中文及 Unicode 容易碰到的问题。

Unicode 编码基础

这里非常简单的讲一下编码知识,此部分表述可能不太准确,如果你对 Unicode 更为了解的话请联系我帮忙纠正。

你可以想象 Unicode 是一个很大的表,里面有着世界上所有的文字的个体,如英文中的字母,中文的汉字。事实上 Unicode 标准中每一个字都有一个唯一对应的编号,好比说 '中'字 对应十六进制 0x4E2D,而字母 'a' 对应的是十六进制 0x0061。这个编号是由 Unicode Consortium 这个组织来确定的。 如果说用这个编码来对应字符来用于表示字符,理论上是可以的,这样的话就是每一个数字编号能对应一个字符。

而实际情况中,不是每篇文章都用得到世界上所有的字符。譬如一篇英文文章就只有英文字母加上一些符号,用 Unicode 来进行存储的话每个字符要浪费太多的空间。所以就有各种类型的编码产生。编码我们这里可以理解就是将一部分的 Unicode (比如说所有的中文,或者所有的日文)字符,以某种方式确定另外一个符号来代表他。中文常用编码有 UTF8 和 GBK,仍然以 '中'字 为例, UTF8 编码将对应 '中'字 的 Unicode 编号 0x4E2D拆成三个的编号的组合,[0xE4, 0xB8, 0xAD],只有这几个连在一起的时候才会被作为一个 '中'字 显示出来;作为对比,GBK 编码将 '中'字 对应的 Unicode 编号 0x4E2D编码成为两个编号的组合
[0xD6, 0xD0],在 GBK 编码环境下只有这两个编号一起时,才会显示为 '中'字。

上面的例子中,如果把 UTF8 编码后的 [0xE4, 0xB8, 0xAD]放到 GBK 环境下来显示会怎样?这几个编号跟 '中'字 在 GBK 下的编码 [0xD6, 0xD0]
,不同,则显然不会显示为 '中'字。这三个字符会跟排在其前后的字符一起,按照 GBK 的编码规则找有没有对应的字符。结果有可能显示出一个毫不相关的字符,有时候为符号或者干脆不显示,这种情况就算产生了乱码。

Python 2.x 中的 String 与 Unicode

在 Python 2.x 中是有两种字串符相关类型的,分别为 String 和 Unicode,两者提供的接口非常类似,有时候又能自动转换,蛮容易误导人的。在 Python 3 中 这两个类型分别用 Bytes 和 String 替代了。这个名字更能说明两者的本质:Python 2.x 中的 String 中存储的是没有编码信息的字节序列,也就是说 String 中存储的是已经编码过后的序列,但他并不知道自身是用的哪种编码。相反的 Unicode 中存储的是记载了编码的字串信息,其中存储的就是相应字符的 Unicode 编号。在这里用程序来说明,我们建立一个简单的脚本名字为 encoding.py,代码如下:


#!/usr/bin/python  
# -*- coding: utf-8 -*-    
strs = "这是中文"  
unis = "这也是中文".decode("utf8")    
print strs[0:2]  
print unis[0:2].encode('gbk')    
print len(strs)  
print len(unis)  

前面两行后面会解释到,就是限定运行环境以及该脚本文件的编码格式。此脚本在这里可以下载,如果你要自己写的话请务必确保脚本的编码是 utf8 而不是别的。在 Windows 下的运行结果在这里,我觉得正好能说明问题:


C:\SHARED\Dev\scripts>encoding.py

这里需要说明,我们的程序是 UTF8 编码,主要意义是该程序中的所有直接写出来的字串符(用"", ''括起来的字串符)是运用 UTF8 格式编码的;然而Windows 下的命令行是 GBK 环境。这里 strs是一个 String。事实上在 Python 2.x 中直接写在程序中的字串符,其类型都是 String(这里不考虑 string literal)。我们先直接输出 strs[0:2],得到的是一个乱码字符(这个字符只是碰巧凑成是一个字)。如上面说的,String中存储的是没有编码信息的字串序列,这里就是将strs中前两个编号取出并尝试显示。由于命令行环境为 GBK 编码,这里对应的字碰巧凑成了一个字,但是跟原本的字没有任何关系。


  unis是由一个 String调用 decode()方法得到,这正是在 Python 2.x 中取得 Unicode的最基本的方式。由于 String并不知道它本身是由什么编码格式来进行的编码,这里是我们的责任来确定他原来是用哪种编码方式进行编码。我们知道代码中的编码格式是 UTF8,所以我们可以用调用 String的 decode()方法来进行反编码,也就是解码, 把字串符从某种编码后的格式转换为其唯一对应的 Unicode 编号。unis为解码获得的结果,其在 Python 2.x 中对应类型就是 Unicode,其中存储的就是 每个字符对应的 Unicode 编号。

我们尝试输出 unis的前两个字符,在这里我们调用了 Unicode的 encode()方法。这就是编码的过程。我们知道 Windows 命令行下的编码是 GBK,只有采用 GBK 编码的字符才能正确显示。所以在这里我们通过调用 Unicode的 encode()方法,将 unis中存储的 Unicode 编号 按照 GBK 的规则来进行编码,并输出到屏幕上。这里我们看到这里正确的显示了 unis中的前两个字符。要注意的是在命令行中直接 print Unicode的话 Python 会自动根据当前环境进行编码后再显示,但这样掩盖了两者的区别。建议总是手动调用 encode和 decode方法,这样自己也会清楚一些。

后面两者长度的差别也是佐证我们之前的例子。
strs中存储的是 UTF8 编码后的编号序列,上面看到一个中文字符在 UTF8 编码后变成三个连续的,所以 strs长度为 3x4 = 12。你可以想象 strs中存放的并不是中文,而是一系列没有意义的比特序列;而 unis中存储的是对应的中文的 Unicode 编码。我们知道每一个字符对应一个编号,所以五个字对应五个编号,长度为 5。避免,和解决编码产生的问题

了解了 Python Unicode 编码解码的这些概念后,我们来看看如何尽量的避免遇到让人烦心的编码问题。

首先如果你的代码中有中文,那么一定要务必声明代码的编码格式。根据 PEP-0263 中的介绍,在程序的最开始加上以下两行注释就能确定编码:


#!/usr/bin/python  
# -*- coding: utf-8 -*-  

其中 utf-8就是指定的编码格式。事实上你应该总是使用 UTF8 作为你 Python 程序的编码格式,因为未来的 Python 3 所有文件都将默认以 UTF8 编码。另外除了声明,你必须确定你用来编辑 Python 程序的编辑器是不是真的以 UTF8 编码来存储文件。

之后就是养成关于编码解码的好习惯。当你的程序有 String作为输入时,应该尽早的将其转换为 Unicode,再在程序中进行处理。再输出的时候,也要尽可能玩,直到最后输出的时刻才将 Unicode编码为所需编码格式的 String进行输出。同样的你必须保持你程序内部所有参与运算的字串都是 Unicode格式。很多著名的 Python 库例如 django 就是采用的这种方式,效果也蛮好。千万不要依赖 Python 自己进行两者之间的转换,也不要将 String和 Unicode放在一起运算,这些行为一方面十分容易引起错误,另一方面在 Python 3 中已经无法再现。虽说确定 String的编码格式是程序员的责任,但有时候你真的不知道有些字串符到底是什么编码的。这里有一个神奇 chardet 能够帮助你。以下是摘自其页面上的例子,很好了说明了它的作用:读入任意一串字符,猜测其编码格式,并且给出猜测的确信度。


>>> import urllib  
>>> urlread = lambda url: urllib.urlopen(url).read()  
>>> import chardet  
>>> chardet.detect(urlread("http://google.cn/"))  {'encoding': 'GB2312', 'confidence': 0.99}    
>>> chardet.detect(urlread("http://yahoo.co.jp/"))  {'encoding': 'EUC-JP', 'confidence': 0.99}   
>>> chardet.detect(urlread("http://amazon.co.jp/"))  {'encoding': 'SHIFT_JIS', 'confidence': 1}    
>>> chardet.detect(urlread("http://pravda.ru/"))  {'encoding': 'windows-1251', 'confidence': 0.9355}  

如果 confidence 非常低的话或者 chardet 直接报错,多半是字串经过多次错误编码解码,要从别的地方找办法解决问题。

如果上面的介绍还不能让你理解 Unicode 的概念,这里还有几篇关于这个问题的文章:

介绍 Unicode 的两篇文章 [1], [2]。关于 Unicode 有更为详细的解释。

Unicode In Python, Completely Demystified 特别针对 Python 下的 Unicode 处理进行详细的讲解。

其他除了上面几个重要的问题之外,剩下的资源。


Vim Python开发 相关资源

事实上我现在自己是在用 Vim 写 Python,感觉也蛮不错。以下是相关资源。


 

UltimateVimPythonSetup 比较新的一个专门针对 Python 的 Vim 配置文件。


 

Vim as Python IDE 只要搜 Python 和 Vim 就一定会找到这一篇文章。


 

vimcolorschemetest 所有的Vim 配色方案都在集结在这里。


 

Python 相关 Vim 插件


pythoncomplete.vim   按上面的介绍配置一下,在自动输入的时候按Ctrl-X, Ctrl-O就有很强力的自动补全了。
python.vim        加强语法的高亮。
pyflakes.vim       很棒的语法检查,分析你的语法看避免低级错误。注意这个在Vim7.2下才有用, 如果是7.1则一点效果都没有...

其他相关资源

用Python做科学计算
  这个把Python(x,y)里面所有的模块基本上都讲了一遍,我觉得外国人肯定都希望这个有个英文版的。


 

PyMOTW
  这个名字看起来像个Python库(其实它还真的是一个...),但他总体来说其实是一份文档, "Python每周一个模块"。作者持续几年每周介绍一个Python标准库中的库。你可以把他看做是一个Python标准库文档的一个很棒的补充,当你看标准库中的介绍看的云里雾里的时候,不妨来这边找找相应的介绍。因为这里的例子给的很全,而且基本上你用的到的偏门的库这里都有介绍哦。另外一个好消息是PyMOTW有一份很棒中文翻译版


 

reddit.com/r/pythonpython.org planet
  Python 相关的文章和资源。就我个人经历来说,每次都能在这里看到很多有用的东西。


 

posted @ 2011-03-24 15:44  牛皮糖NewPtone  阅读(43138)  评论(2编辑  收藏