python漫游指南

上传人:第*** 文档编号:61701617 上传时间:2018-12-10 格式:PDF 页数:118 大小:1.31MB
返回 下载 相关 举报
python漫游指南_第1页
第1页 / 共118页
python漫游指南_第2页
第2页 / 共118页
python漫游指南_第3页
第3页 / 共118页
python漫游指南_第4页
第4页 / 共118页
python漫游指南_第5页
第5页 / 共118页
点击查看更多>>
资源描述

《python漫游指南》由会员分享,可在线阅读,更多相关《python漫游指南(118页珍藏版)》请在金锄头文库上搜索。

1、Python Guide Documentation发发发布布布 0.0.1Kenneth Reitz2017 年 08 月 18 日Contents1开开开始始始吧吧吧31.1选择一个解释器 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .31.2正确地安装Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51.3在Mac OS

2、 X安装Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .51.4在Windows上安装Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .71.5在Linux上安装Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .82写写

3、写出出出优优优雅雅雅的的的代代代码码码112.1组织好你的项目 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .112.2代码风格 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .212.3阅读优秀代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

4、. . . . . . . . . . . . . . . .302.4文档. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .312.5测试你的代码 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .342.6日志. . . . . . . . . . . . . . . . . . . . . . . . . .

5、 . . . . . . . . . . . . . . . . . . . . . . . . .382.7常见的问题. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .412.8选择许可证. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .443Python应应应用用用场场场景景景453.1网络应用 . . . . . . .

6、 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .453.2Web应用及框架 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .463.3HTML页面爬取 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .523.4命令行应用

7、. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .533.5GUI应用 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .543.6数据库 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

8、. . . . .563.7网络. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .583.8Systems Administration . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .583.9Continuous Integration . . . . . . . . . . . . . . . . . . . . . . .

9、. . . . . . . . . . . . . . . . . . .633.10Speed . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .643.11Scientific Applications . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .713.12Image Manipulation . . . . . .

10、. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .733.13Data Serialization. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .743.14XML parsing . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .753.1

11、5JSON . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .763.16Cryptography . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .773.17Machine Learning . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

12、. . . . . . . . . . . . . . .773.18Interfacing with C/C+ Libraries. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .804Python代代代码码码打打打包包包83i4.1Packaging Your Code. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .834.2Freezing Your Code. . . . . .

13、 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .855Python开开开发发发环环环境境境895.1Your Development Environment . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .895.2Virtual Environments . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

14、. . . . . . .945.3Further Configuration of Pip and Virtualenv . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .976附附附加加加说说说明明明996.1Introduction. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .996.2The Community. . . . . . . . . . . . . . . . .

15、. . . . . . . . . . . . . . . . . . . . . . . . . . . . 1006.3Learning Python . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1016.4Documentation . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1066.5News . . . . .

16、 . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1076.6Contribute. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 1086.7License . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .

17、 . . . . . . . . . 1096.8The Guide Style Guide . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . 109iiPython Guide Documentation, 发发发布布布 0.0.1地球人,你们好!欢迎来到Python漫游指南。这这这是是是一一一份份份生生生动动动的的的、栩栩栩栩栩栩如如如生生生的的的指指指南南南。 如果您有意贡献内容, 在GitHub上fork我!这份手写指南着眼于Python的安装、配置和日常使用,旨在为新

18、手和专业的Python开发者在提供一份最佳实践。这是一份充满 自自自我我我见见见解解解 的指南,内容与Python官方文档大相径庭。这份指南不会是简单的罗列每一个Python框架,取而代之,我们会提供一系列实用而又精炼的建议。那么开始吧!开始之前,首先要确定你明白自己的毛巾在哪里。译译译者者者注注注: 银河系漫游指南曾经明确指出,毛巾是对一个星际漫游者来说最有用的东西, 至于为什么,我也不知道,因为我也没看过。Contents1Python Guide Documentation, 发发发布布布 0.0.12ContentsCHAPTER1开开开始始始吧吧吧Python菜鸟? 来,先教你如何正

19、确配置Python环境。选选选择择择一一一个个个解解解释释释器器器Python的的的现现现状状状 (3 & 2)当选择Python解释器的时候,总会面临一个问题:“我该使用Python 2还是Python 3呢?” 答案并不会像我们想的那么明确。Python现状如下:1. 当前大部分生产级应用采用Python 2.7。2. 当前Python 3已经可以用于生产级别的应用了。3. Python 2.7将只会接受必要的安全更新,直到2020年6。4. 现在”Python”这个名字指代Python 3和Python 2。瞧,你也可以看到,这就是为什么不那么容易选择。建建建议议议我就直接说了: 对于新

20、的项目,使用Python 3。 如果你是刚开始学习Python,熟悉下Python 2.7还是非常值得的,但还是推荐去学习Python 3,那会更加有用。 都学以下。它们都是“Python”。 目前已经构建的很多软件通常依赖于Python 2.7。 如果你正在开发新的开源Python库,最好同时支持Python 2和Python 3。对于想要被广泛使用的新库,如果你说只支持Python 3,那么这种政治声明会让很多用户疏远。 当然,同时支持两个版本不算多大个问题,接下来三年,这种情况会逐渐越来越少。6https:/www.python.org/dev/peps/pep-0373/#id23Py

21、thon Guide Documentation, 发发发布布布 0.0.1那那那么么么,用用用Python 3咯咯咯?如果你要选择Python解释器,那么我推荐使用最新的Python 3.x, 因为每个新版本都会在标准库、安全性以及BUG修复上有所提升。然而,如果你有很重要的原因只能使用Python 2,例如处理已经存在的Python 2代码、用到了Python 2独有的库、因为感觉更简单熟悉, 或者像我一样,极度喜欢Python 2,那么就使用Python 2。这也没什么坏处。通过 Can I Use Python 3? 可以检查你依赖的软件是否会妨碍你采用Python 3。进一步阅读编写

22、同时支持Python 2.6、2.7和Python 3 的代码是完全有可能的。至于难易程度,取决于你所编写软件的类型。如果你是新手,优先考虑其他更重要的方面更切实际。实实实现现现当人们讨论 Python 的时候,通常不仅仅意味着这门编程语言,同时也指CPython实现。Python 实际上是一个规范,该规范有多种实现方式。CPythonCPython 是用C语言编写的一种参考实现,它会把Python代码编译成中间字节码供虚拟机来解释执行。CPython对Python的包和C扩展模块提供了最高程度的兼容。如果你正在编写基于Python的开源代码,并且想让尽可能多的人受益,CPython可以说是最

23、好的选择。如果使用的包依赖于C扩展,那么唯一的可选实现也只有CPython。所有版本的Python语言都是C实现的,因为CPython是其参考实现。PyPyPyPy 是RPython实现的解释器,RPython是Python的子集,具有静态类型。这个解释器的特点是带有JIT编译器并且支持多种后端(C,CLI,JVM)。PyPy的目标是在提高性能的同时,最大限度的保持与CPython参考实现的兼容性。如果你想提高自己Python代码的性能,PyPy值得一试。在一套测试基准下,目前会 比CPython快5倍以上 。PyPy支持Python 2.7。PyPy31, 目前处于beta阶段,支持Pyth

24、on 3。JythonJython 是Python的另一种实现,它会把Python代码编译为Java的字节码,然后被JVM(Java虚拟机)执行。另外,该实现也可以像使用Python模块一样来使用Java的类。如果你需要与现有的Java代码进行交互,或者有其他原因需要在JVM上使用Python,Jython是最好的选择。Jython目前支持到Python 2.7。21http:/pypy.org/compat.html2https:/hg.python.org/jython/file/412a8f9445f7/NEWS4Chapter 1. 开开开始始始吧吧吧Python Guide Docu

25、mentation, 发发发布布布 0.0.1IronPythonIronPython 是.NET框架上的实现。可以同时使用Python和.NET的库,并且可以让.NET上的其他语言来调用所写的Python代码。Python Tools for Visual Studio 把IronPython直接集成到了Visual Studio开发环境中,给Windows上的开发者提供了一个不错的选择。IronPython支持Python 2.7。3PythonNetPython for .NET 作为一个包,为本地已安装的Python和.NET公共语言运行时(CLR)提供了无缝的集成。它采取与IronP

26、ython (见上文)相反的方法,与其说是竞争,不如说是互补。通过结合Mono,pythonnet可以让安装在非Windows操作系统(比如OS X和Linux)上的Python与.NET框架进行互操作。除了IronPython外,它也是可以毫无冲突运行的。Pythonnet支持范围从Python 2.6到Python 3.5。4 5 如何正确地安装Python1.2 正正正确确确地地地安安安装装装Python其实,在你的系统中很可能已经内置安装好了Python。如果是这样的话,不用额外的安装或者配置就能使用到Python。当然了,虽然话是这么说地,但还是强烈建议在真正使用Python做实际开

27、发前,按照下面指南中描述的步骤安装Python的工具和库。特别是Setuptools、Pip和Virtualenv这几个工具一定要安装 - 它们会让你更方便地使用其他第三方的库。安安安装装装指指指南南南这部分内容涉及了 Python 、setuptools、pip以及virtualenv 的安装设置,为后续开发做准备。 Python 3 on MacOS. Python 2 on MacOS. Python 2 on Microsoft Windows. Python 2 on Ubuntu Linux.在在在Mac OS X安安安装装装Python注注注解解解: 查看 如何在OS X中安装P

28、ython 3.最新的Mac OS X,Sierra 带带带有有有开开开箱箱箱即即即用用用的的的Python 2.7 。3http:/ 正正正确确确地地地安安安装装装Python5Python Guide Documentation, 发发发布布布 0.0.1虽然说使用Python前不需要额外的安装或者配置,但是我强烈建议你在开始构建Python应用程序前,按照下一节描述的步骤安装工具和库。特别的,任何时候你都该安装Setuptools和pip,这样会让你更方便的使用其他第三方Python库。OS X自带的Python版本对于学习来说绰绰有余,但是却不太适合用来开发。与 官方当前的版本相比,自

29、带的Python版本太旧了,没有达到生产环境稳定性的要求。正正正确确确的的的方方方式式式接下来我们安装一个真正的Python。在安装Python前,需要先安装一个C编译器。通过运行 xcode-select -install 可以以最快方式安装Xcode命令行工具。你也可以从Mac应用商店下载完整版本的 Xcode ,或者是最小化的非官方版本 OSX-GCC-Installer 。注注注解解解: 如果你已经安装了Xcode或者计划使用Homebrew,那就不要安装OSX-GCC-Install。同时安装二者时,软件会出现问题,并且很难诊断出原因。注注注解解解: 如果是全新安装的XCode,还需

30、要通过在终端运行 xcode-select -install 来添加命令行工具。尽管OS X自带了大量的UNIX工具集,但是熟悉Linux系统的开发人员会发现缺少一个关键的组件:一个像样的包管理工具。Homebrew 填补了这块空白。为了 安装Homebrew ,需要打开 Terminal 或者你最喜欢的OSX终端模拟器,然后执行如下命令:$ /usr/bin/ruby -e $(curl -fsSL https:/ /.profile 中,来把Homebrew目录添加到环境变量 PATH 。export PATH=/usr/local/bin:/usr/local/sbin:$PATH接下来

31、,我们就可以安装Python 2.7:$ brew install python或者Python 3:$ brew install python3这会花费一两分钟。Setuptools & PipHomebrew也会安装Setuptools和 pip。Setuptools可以让你通过一个命令 easy_install 在网上下载和安装任何兼容的Python软件包。同时也可以很方便的利用它们在自己开发的Python软件里添加网络安装功能。pip 是一个易于安装和管理Python包的工具,相比于 easy_install 更加推荐 pip 。它在 几个方面 要更加优于 easy_install ,

32、并且维护良好。6Chapter 1. 开开开始始始吧吧吧Python Guide Documentation, 发发发布布布 0.0.1虚虚虚拟拟拟环环环境境境虚拟环境主要是通过为各自创建虚拟的Python环境,把不同项目所依赖的包分隔在各自独立的空间内。这样就能解决“项目X依赖版本1.x,但是项目Y需要版本4.x”的窘境,同时保持全局site-packages目录的干净和可管理性。例如,你可以在一个需要Django 1.10的项目上进行开发工作,同时维护一个依赖Django 1.8的项目。请参考文档 虚拟环境 来使用。也可以使用 virtualenvwrapper 来更简单的管理你的虚拟环境

33、。本章是 另外一篇文章 的修改合成版本,与原文使用同样的许可证。在在在Windows上上上安安安装装装Python首先,到官网下载Python 2.7的 最新版本 。如果你想确保安装的是最新版本,在 官网主页 上点击Downloads Windows链接。Windows的Python以MSI的格式提供,双击即可安装。MSI格式的文件允许Windows管理员使用标准工具来自动化安装。按照设计,Python会安装到带有版本号的目录中,例如,Python 2.7会安装到 C:Python27 ,这样可以在系统上安装多个版本而不引起冲突。当然,对于Python文件,只能有一个默认解释器。这种安装方式也

34、不会自动修改环境变量 PATH ,这样你就可以控制运行哪个Python版本。如果使用时,每次都要输入Python解释器的完整路径,显得太麻烦,所以最好把默认版本的Python目录添加到环境变量 PATH 。假设你的Python安装位置是 C:Python27 ,把下述内容添加到 PATH :C:Python27;C:Python27Scripts在 powershell 中运行下列命令可以很容易做到这点:Environment:SetEnvironmentVariable(Path, $env:Path;C:Python27;C:Python27Scripts, User)当安装Python包

35、时,一些新的命令会放置在上面的第二个目录( Scripts )中,所以把这个目录添加到环境变量中是很有用的。虽然说使用Python前不需要额外的安装或者配置,但是我强烈建议你在开始构建Python应用程序前,按照下一节描述的步骤安装工具和库。特别的,任何时候你都该安装Setuptools和pip,这样会让你更方便的使用其他第三方Python库。Setuptools + Pip最至关重要的的第三方Python软件是Setuptools,该工具扩展了标准库中disutils的安装和打包功能。一旦安装好它们,你就可以使用一个简单的命令来下载、安装、卸载任何兼容的Python软件包。同时也可以很方便的

36、利用它们在自己开发的Python软件里添加网络安装功能。通过运行 ez_setup.py 这个脚本可以获得Windows上最新的Setuptools。这时候就会新出现一个可以使用的命令:easy_install。不过这个命令已经被很多人认为废弃了,所以我们需要安装它的替代:pip。不像easy_install,Pip允许卸载安装好的包,并且维护也很活跃。运行脚本 get-pip.py 可以安装pip。1.4. 在在在Windows上上上安安安装装装Python7Python Guide Documentation, 发发发布布布 0.0.1虚虚虚拟拟拟环环环境境境虚拟环境主要是通过为各自创建虚

37、拟的Python环境,把不同项目所依赖的包分隔在各自独立的空间内。这样就能解决“项目X依赖版本1.x,但是项目Y需要版本4.x”的窘境,同时保持全局site-packages目录的干净和可管理性。例如,你在一个需要Django 1.10的项目上进行开发,同时维护一个依赖Django 1.8的项目。请参考文档 Virtual Environments 来使用。也可以使用 virtualenvwrapper 来更简单的管理你的虚拟环境。本章是 另外一篇文章 的修改合成版本,与原文使用同样的许可证。在在在Linux上上上安安安装装装Python在最新版的CentOS、Fedora、Redhat En

38、terprise(RHEL)以及Ubuntu上已经 搭搭搭载载载了了了开开开箱箱箱即即即用用用的的的Python 2.7。如果想查看自己安装的Python是什么版本,打开命令行运行如下命令:$ python -version一些老版本的RHEL和CentOS自带的Python 2.4对于现在的Python开发来说是无法接受的。幸运的是,存在 Extra Packages for Enterprise Linux ,这些包都基于Fedora的高质量包,而Fedora可以说是RHEL的试验场。这个仓库包含的Python 2.6包是定制的,可以与系统自带Python 2.4的包一一对应的安装。虽然说

39、使用Python前不需要额外的安装或者配置,但是我强烈建议你在开始构建Python应用程序前,按照下一节描述的步骤安装工具和库。特别的,任何时候你都该安装Setuptools和pip,这样会让你更方便的使用其他第三方Python库。Setuptools & Pip最至关重要的两个第三方Python包是 setuptools 和 pip。一旦安装好它们,你就可以使用一个简单的命令来下载、安装、卸载任何兼容的Python软件包。同时也可以很方便的利用它们在自己开发的Python软件里添加网络安装功能。默认情况下,Python 2.7.9及之后(Python2系列)以及Python 3.4及之后的版

40、本都已经包含了pip。如果想知道pip是否已经安装,只需要打开命令行输入以下命令:$ command -v pip如果想自己安装pip,参考官方pip的安装教程 - 这样会自动安装setuptools的最新版本。虚虚虚拟拟拟环环环境境境虚拟环境主要是通过为各自创建虚拟的Python环境,把不同项目所依赖的包分隔在各自独立的空间内。这样就能解决“项目X依赖版本1.x,但是项目Y需要版本4.x”的窘境,同时保持全局site-packages目录的干净和可管理性。例如,你可以在一个需要Django 1.10的项目上进行开发,同时维护一个依赖Django 1.8的项目。请参考文档 虚拟环境 来使用。也

41、可以使用 virtualenvwrapper 来更简单的管理你的虚拟环境。8Chapter 1. 开开开始始始吧吧吧Python Guide Documentation, 发发发布布布 0.0.1本章是 另外一篇文章 的修改合成版本,与原文使用同样的许可证。1.5. 在在在Linux上上上安安安装装装Python9Python Guide Documentation, 发发发布布布 0.0.110Chapter 1. 开开开始始始吧吧吧CHAPTER2写写写出出出优优优雅雅雅的的的代代代码码码本章主要聚焦于编写Python代码的最佳实践。组组组织织织好好好你你你的的的项项项目目目这里的 “组织

42、” 意思是,为了让你的项目能达到最佳目标而做出的抉择。我们需要考虑如何最大限度的利用Python的特性来创建简洁高效的代码。从实际中的角度来说,”组织” 就是为了让代码的逻辑和依赖足够清晰明了,类似于文件系统中文件和目录的组织那样一目了然。哪些功能应该在哪些模块?项目中的数据流是如何进行的?哪些特性和功能应该被组织到一起或者分离开?通过回答这类问题就可以开始对你的项目有一些计划,换言之就是你对最终的产品形态有了一定的想法。本节我们将详细了解Python的模块和导入系统,因为这两部分是组织好一个项目的核心元素。然后,我们会从多个方面讨论如何构建具有高扩展性和可靠性的代码。仓仓仓库库库的的的组组组

43、织织织是是是的的的,这这这很很很重重重要要要!正如在一个健康的开发周期中,代码风格、API设计以及自动化都是必不可少的一样,项目仓库的组织可以说是项目 架构 中最为关键的一部分。当一个潜在的用户或者贡献者来到项目仓库的页面,他们会看到以下一些东西: 项目名 项目描述 一大堆的文件只有当他们的滚动条到达目录的下方时,才会看到项目的README。如果你的仓库里面是一大堆垃圾一样的文件或者各种杂乱嵌套的目录,即使你的文档再优秀,这些人也很有可能在阅读之前已经跑去其他地方了。如果你以后想当总统,就不能穿的像个打工仔。当然,第一印象不能代表一切。你和你的同伴可能会花费不计其数的时间在这个仓库上,最终对于

44、项目里的各种犄角旮旯都能如数家珍。总之,仓库的设计依然是很重要的。11Python Guide Documentation, 发发发布布布 0.0.1示示示例例例仓仓仓库库库tl;dr(太太太长长长了了了,不不不读读读了了了): 这就是 Kenneth Reitz 的建议。下面这个仓库 在GitHub 上可以找到。README.rstLICENSEsetup.pyrequirements.txtsample/_init_.pysample/core.pysample/helpers.pydocs/conf.pydocs/index.rsttests/test_basic.pytests/tes

45、t_advanced.py我们来讨论下里面的一些细节。真真真正正正的的的模模模块块块部部部分分分位置./sample/ or ./sample.py用途感兴趣的项目核心代码这个模块是仓库的核心部分,这部分不应当被隐藏起来。./sample/如果你的模块仅仅包含一个单独的文件,你可以把这个文件直接放在仓库的根目录下。./sample.py你的这个库不应该放在一个模棱两可、叫做src的目录或者名为python的子目录。许许许可可可证证证位置./LICENSE用途法律说明这可以认为是除了代码本身之外仓库中最为重要的一部分。许可证的全文和版权申明都在这个文件中。如果你不确定使用哪种许可证,到这里看看

46、 。当然了,你也可以不用包含许可证,不过这可能会潜在的阻碍许多人使用你的代码,毕竟怕出什么幺蛾子。Setup.py位置./setup.py用途打包与分发管理如果你的模块包在仓库的根目录下,很显然这个文件也应该在根目录下。12Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1依依依赖赖赖说说说明明明文文文件件件位置./requirements.txt用途项目开发中的依赖pip依赖文件 应该放置在仓库的根目录下。这个文件应该详细列出项目所依赖的库,包括测试、构建以及文档生成所用到的。如果你的项目没有依赖,

47、或者你更喜欢用 setup.py 来设置,那这个文件也可以不需要。文文文档档档位置./docs/用途包的说明文档毫无疑问,这部分别无他处。测测测试试试套套套件件件位置./test_sample.py or ./tests用途包的集成测试和单元测试开始的时候,测试套件通常可能只是一个单独的文件:./test_sample.py一旦测试套件增多,就应该把这些测试移到一个目录中,就像下面这样:tests/test_basic.pytests/test_advanced.py很明显,这些测试模块需要从核心代码模块中导入来进行测试。具体可以通过以下几种方式: 假设待测试的包已经预先安装在site-pac

48、kages中。 使用简单(但是 显式 )的方式修改路径来正确的解析出包。本人强烈推荐后一种方式。让一个开发人员通过运行 setup.py develop 来测试还在不断变化的代码,这种方式要求为每次改变后的代码部分设置隔离环境,太不友好了吧。为了给测试提供独立的导入上下文,创建一个tests/context.py文件:import osimport syssys.path.insert(0, os.path.abspath(.)import sample然后在这个独立测试模块中,按如下方式导入待测试模块:from .context import sample不管安装位置在哪里,这种方式总会按照

49、预期工作。一些人主张分发代码模块的同时一并分发测试代码 本人是反对的。这样通常会给你的用户增加复杂性,许多测试套件通常需要额外的依赖和运行时上下文。2.1. 组组组织织织好好好你你你的的的项项项目目目13Python Guide Documentation, 发发发布布布 0.0.1Makefile位置./Makefile用途通用任务管理如如如果你留意我的大部分项目或者Pocoo团队的任何一个项目,你会注意到都有一个Makefile文件。为啥?这些项目并不是C语言写的. 简而言之,make是一个极其有用的任务管理工具,可以简单的定义项目中常见的任务。(译者注:为毛不是SCons?)Makefi

50、le示示示例例例:init:pip install -r requirements.txttest:py.test tests.PHONY: init test其他常见的管理脚本(例如 manage.py 或者 fabfile.py )也应当在仓库的根目录下。关关关于于于Django应应应用用用自从Django 1.4发布以后,我在Django应用中注意到了一种新的趋势。由于Django自带的新模板系统,导致许多开发者把他们的项目仓库组织的很糟糕。怎么个糟糕法?这么说吧,他们会进入新建的仓库目录,然后一如往常的执行如下命令:$ django-admin.py startproject samp

51、lesite其结果就是仓库结构看起来如下:README.rstsamplesite/manage.pysamplesite/samplesite/settings.pysamplesite/samplesite/wsgi.pysamplesite/samplesite/sampleapp/models.py别再这么干了,伙计。重复的路径会让你的工具和开发人员产生迷惑。不必要的嵌套与人无益(除非他们依然怀念庞大的SVN仓库)。正确的做法是:$ django-admin.py startproject samplesite .注意最后的那个 “.“。这种方式操作的结果如下:README.rstma

52、nage.pysamplesite/settings.pysamplesite/wsgi.pysamplesite/sampleapp/models.py14Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1代代代码码码的的的组组组织织织是是是关关关键键键受益于Python处理导入和模块的方式,Python项目的组织相对容易很多。这里说的容易是指模块导入的概念很容易理解,并且不会受到太多的约束。因此,你可以更专注于项目中不同部分的交互,专注于纯架构上的任务。换句话说,一个项目很容易组织也意味着可能会组

53、织的很糟糕,毕竟组织起来可能会很随意。以下是一些糟糕组织方式的信号: 数量众多且杂乱的循环依赖:如果文件 furn.py 中的类Table和Chair需要导入文件 workers.py 中的类Carpenter(木匠),以便可以回答类似 table.isdoneby() 的问题,同时类Carpenter也需要导入Table和Chair来回答 carpenter.whatdo() 的问题,这时候就会产生循环依赖。这时候,你不得不采用一些奇技淫巧来解决这个问题,比如在方法或者函数中使用导入语句。 隐式耦合:每当对Table的实现进行微小改变时,就会由于破坏了Carpenter中的代码,进而导致不相

54、关的测试套件中20来个测试无法运行,因此需要在修改时做小心翼翼的诊断工作。这也就意味着你对Carpenter代码中的Table需要做太多的假设,反之亦然。 大量使用全局变量或者上下文:Table和Carpenter依赖全局变量,而不是通过显示的互相传递(height, width, type, wood) 来进行交互,而这些全局变量是可以被不同地方动态修改的。为了知道矩形的桌子为什么突然变成了正方形,你需要仔细检查每一个可能会接触到全局变量的地方,然后又发现远程模板代码也正在修改相关的上下文环境,使得桌子的外形更加难捉摸。 意大利面条式代码:所谓的意大利面条式代码就是占了几页的if语句和循环语

55、句,同时还伴随着一坨没有良好分界、纯粹复制黏贴过来的代码。Python中通过缩进来组织代码的方式(这也是最有争议的一个特性)使得维护这样的代码很费力。不过好消息是,你不会见到很多这样的代码。 意大利饺子式代码:这种代码在Python中更常见,包含了数以百计相似的逻辑代码,这些代码片段都很小,通常是没有很好组织的类或者对象。就之前的题目而言,如果你从来没想到是否该用FurnitureTable、AssetTable或者Table甚至TableNew来完成手头的工作,那么你很可能已经在意大利饺子式的代码中遨游了。模模模块块块Python的模块可以说是目前已知的主要抽象层中的一个,也可能是最为自然的

56、一个。抽象层允许把代码分割开来,与具体的数据和功能部分放在一起。例如,项目中的一层可以处理与用户操作进行的对接部分,另一层处理低层次的数据操作。分离这两部分最自然的方式就是把接口性功能的代码放置在一个文件中,所有低层次操作放在另一个文件中。这种方式下,包含接口代码的文件需要导入包含低层次操作代码的文件。可以通过 import 和 from .import语句来实现。一旦你使用了 import 语句,你就已经使用了模块。这些模块可能是类似 os 和 sys 的内置模块,环境中安装的第三方模块,抑或是项目中的内部模块。为了与风格指南章节部分保持一致,模块名应该简短、小写,并且避免使用点号(.)或者

57、问号(?)等特殊符号。所以,my.spam.py 这种文件名是应当避免的!如此命名会干扰到Python查找模块的方式。在 my.spam.py 这种命名的情形中,Python会解释为去名叫 my 的目录中查找 spam.py 文件,显然这不是我们的初衷。这里有一个 示例 ,很好的说明了点号应当如何使用。尽管你可以按照你的想法把你的模块命名为 my_spam.py,但是尽量少在模块名中使用下划线。除了一些命名限制,没有其他特殊要求,Python文件就可以看作一个模块,但是,如果你想正确的使用模块的概念,避免一些问题,最好还是真正理解导入机制的原理。具体来说,语句 import modu 会寻找同

58、一目录下的文件 modu.py 作为调用者。如果同目录下没有找到,Python解释器会递归的在”path”中查找文件 modu.py,如果都没有找到,则引起ImportError的错误。2.1. 组组组织织织好好好你你你的的的项项项目目目15Python Guide Documentation, 发发发布布布 0.0.1一旦文件 modu.py 找到,Python解释器就会在一个独立的作用域中执行这个模块。modu.py 中任何顶层的语句都会被执行,包括从其他模块中引入的那些。函数和类定义会存储到模块的字典里。然然然后,模块中的变量、函数和类就可以在调用者中通过被导入模块的命名空间来使用。命名

59、空间是Python编程中特别有用且功能强大的核心概念。在许多编程语言中,有一个 include file 的指令来让预处理器把被包含文件中的代码拷贝到调用者中。Python中却并不是这样:被包含的代码有自己独立的模块命名空间,这意味着你通常可以不用太担心被包含的代码产生副作用,例如覆盖同名的函数等。通过特殊的导入语法 from modu import*可以模拟更加标准的行为。但这通常被认为是不好的习惯。使使使用用用 import*会会会使使使得得得代代代码码码很很很难难难读读读,不不不知知知道道道导导导入入入了了了些些些什什什么么么,并并并且且且使使使得得得依依依赖赖赖不不不那那那么么么封封封

60、闭闭闭,用用用到到到没没没用用用到到到的的的都都都导导导入入入 。使用 from modu import func 这种方式可以很明确的导入需要的函数,并且放在模块的全局命名空间中。这样带来的危害会远远小于 import*这种方式,因为可以显式的指明全局命名空间中导入的是什么,这种方式对于更简单的 import modu 而言,唯一的优势就是后面可以不用输入模块名,节省了一捏捏的输入成本。不不不好好好的的的方方方式式式.from modu import*.x = sqrt(4)# sqrt是modu的一部分?内置的?还是上面定义的?较较较好好好的的的方方方式式式from modu import

61、 sqrt.x = sqrt(4)# sqrt是modu的一部分,当然了,前提是从import到这里中间没有重新定义过最最最好好好的的的方方方式式式import modu.x = modu.sqrt(4)# 毫无疑问,sqrt就是modu的一部分正如 代码风格 章节提到的,可读性是Python的主要特性之一。可读性意味着避免无用的重复文字和杂乱的东西,因此,Python中花费了不少努力来达到一定程度的简短。但是太简短会导致晦涩,所以简短应该在简洁和晦涩中找到一个平衡点。 modu.func 这种形式可以很直接的说明类或者函数来自哪里,对于不仅仅只包含一个文件的项目来说,可以极大的提高代码的可读

62、性和可理解性。包包包Python提供了非常直接的包系统,就是简单的把模块机制扩展到了目录层面(译者注:模块是基于文件)。任何包含 _init_.py 文件的目录都可以认为是一个Python包。包内的不同模块可以像普通模块那样导入,但是,_init_.py 文件比较特殊,这个文件主要用来把包内部的各种定义集中到一起。目录 pack/ 中的文件 modu.py 可以通过语句 import pack.modu 来导入。该语句会去目录 pack 中寻找文件 _init_.py ,并执行这个文件中的顶层语句。然后再去寻找 pack/modu.py 文件,也执行其中所有的顶层语句。完成这些动作之后,mod

63、u.py 中的任何变量、函数或者类就都可以在pack.modu的命名空间中使用了。一个常见的问题是在 _init_.py 中添加太多的代码。当项目的复杂程度逐渐增加时,目录结构的层次也会随之增加,子包以及子包的子包可能会在处于比较深的目录中。这种情况下,即使只是从子包的子包中导入很简单的一项,也可能需要在遍历目录树的过程中执行所有的 _init_.py 文件。如果包中的模块和子包不需要共享代码时,通常会把 _init_.py 留空,这也是一种比较提倡的行为。16Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布

64、0.0.1最后,对于深层次嵌套的包,有一种比较方便的语法 import very.deep.module as mod 。这可以让你使用 mod 来代替显示的指明 very.deep.module 。面面面向向向对对对象象象编编编程程程Pyhton有时候会被描述为是一种面向对象的语言。这可能稍微有点误导,这里需要澄清一下。在Python中,任何东西都是一个对象,当然也就可以按照对象的方式来处理。比如,这意味着我们可以把函数当作第一类的对象来使用。Python中的函数、类、字符串,甚至是类型都是对象:就像任何其他对象一样,它们有类型,可以作为函数的参数传递,并且可以有自己的方法和属性。从这个意义

65、上理解,Python确实是一种面向对象的语言。然而,不像Java,Python并不强制必须使用面向对象来作为主要的编程范式。对于一些项目来说,不使用面向对象的方式完全可行,比如,可以不使用或者仅仅使用很少的类定义、类继承或者其他面向对象编程特有的机制。此外,正如在 模块 一节中了解的那样,Python处理模块和命名空间的方式让开发人员可以很自然的确保封装性和抽象层次的分离,而这两者恰恰正是使用面向对象最常见的原因。因此,如果项目的业务模型不是必须使用面向对象来进行开发的话,Python程序员可以自由的选择不使用。总会有一些理由避免不必要的面向对象。当我们想要把一些状态和功能粘合在一起的时候,自

66、定义一个类是比较有用的方式。但是,正如在函数式编程讨论中指出的一样,问题恰好出在方程式中“状态”的部分。在一些架构中,典型的例如Web应用,通常需要派生多个Python进程来同时相应外部的请求。这种情形下,在实例化的对象中保存某种状态(通俗点讲就是保存了所在上下文环境的一些静态信息)很容易引起并发问题或者竞争状态。有时候,从一个对象的状态初始化(通常是通过 _init_() 方法来完成)到通过其方法实际使用这个状态之间,上下文环境很可能已经发生变化,保留的状态也可能已经过期。例如,一个请求可能会载入某个条目到内存中,并且标记它已经被用户阅读过。与此同时,如果另一个请求需要删除这个条目,就会导致

67、第一个请求载入的条目被这个请求删除掉,其结果就是我们标记阅读过一条不存在(已删除)的条目,这显然是不合理的。由于这个以及其他一些问题,引发了使用无状态函数这种更好的编程范式的想法。换种说法就是,建议在使用函数中,尽可能的少涉及隐式上下文和可能的副作用。函数的隐式上下文主要是指全局变量以及从函数内部访问的持久层对象。副作用就是指函数对隐式上下文做出了改变。如果函数保存或者删除了全局/持久层的数据,我们就说产生了副作用。小心翼翼地把包含上下文和副作用的函数与包含逻辑处理的函数(纯函数)隔离可以得到如下好处: 纯函数是确定性的:如果输入是固定的,那么输出也一定是相同的。 如果需要重构或者优化时,纯函

68、数更容易改变和替换。 纯函数更容易单元测试:很少需要设置复杂的上下文和清理事后的数据。 纯函数更容易操作、修饰以及传递。总之,在一些架构中,纯函数在构建封闭块的时候比类和对象更有高效,因为没有上下文和副作用。当然了,面向对象还是很有用的,甚至在很多情况下是必须的,比如开发图形桌面应用或者游戏,这种情况下,所操作的实体(窗口、按钮、头像、车辆等)本身在计算机内存中就会有很长的生命周期。装装装饰饰饰器器器Python语言提供了一个简单但是强大的语法,叫做“装饰器”。装饰器本身是一个函数或者类,可以用来包装(或者装饰)其他函数或方法。“被装饰”的函数或方法会替代原来“未装饰”的函数或方法。由于Pyt

69、hon中函数是第一类对象,所以可以通过手动来实现函数的包装,但是使用decorator语法的方式会显得更加清晰,因此也更加推荐这种用法。2.1. 组组组织织织好好好你你你的的的项项项目目目17Python Guide Documentation, 发发发布布布 0.0.1def foo():# do somethingdef decorator(func):# 操作函数return funcfoo = decorator(foo)# 手工装饰decoratordef bar():# Do something# bar()已被装饰装饰器机制对于分离业务非常有用,可以避免外部不相关的逻辑“污染”函

70、数或方法中的核心逻辑。其中一个很好的例子是 记忆表 或者缓存:对于一些运行代价较高的函数,你想把计算结果存在一个表里,以便后面需要的时候可以直接使用而不必重新计算,示例中的这一类功能可以很好的用装饰器来处理。很明显,这部分不能算是函数核心逻辑的一部分。上上上下下下文文文管管管理理理器器器上下文管理器是为一个操作提供额外上下文信息的对象。这个额外的信息采用如下形式来提供:在使用with 语句初始化上下文的时候运行一个可调用对象(译者注:函数或者实现 _call_ 的对象等),同时在执行完 with 块内部的所有代码后,再执行一个可调用对象。使用上下文管理器最为人熟知的例子就是打开一个文件,如下:

71、with open(file.txt) as f:contents = f.read()任何熟悉这种模式的人都知道,以这种方式调用 open 可以确保 f 的 close 方法在后面某个时间点会被自动调用。这可以减轻开发人员的记忆负担,同时也可以使得代码更容易阅读。你自己可以采用两种方式来实现这种功能:使用类或者使用生成器。接下来让我们实现上面提及的功能,首先采用类的方式实现:class CustomOpen(object):def _init_(self, filename):self.file = open(filename)def _enter_(self):return self.fi

72、ledef _exit_(self, ctx_type, ctx_value, ctx_traceback):self.file.close()with CustomOpen(file) as f:contents = f.read()这和普通Python对象没有什么区别,仅仅是多了两个额外的方法,这两个方法会被 with 语句使用。CustomOpen首先被实例化,然后它的 _enter_ 方法会被调用,_enter_ 返回的值会通过语句中的 as f 被赋值到 f。当 with 代码块中的内容被执行完毕时, _exit_ 方法会被调用执行。生成器实现的方式使用了Python内置的 cont

73、extlib:from contextlib import contextmanagercontextmanager18Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1def custom_open(filename):f = open(filename)try:yield ffinally:f.close()with custom_open(file) as f:contents = f.read()这种方式与上述类实现的结果完全一样,尽管简短了很多。首先 custom_open 逐句执行,直到到

74、达yield 语句处,然后把控制权交回给 with 语句, 然后会把 yield 产生的结果通过 as f 赋值到 f上。finally 语句确保无论是否在 with 语句中产生异常,close 都能被调用。由于这两种方式看起来没什么区别,所以我们应该遵循Python之禅来决定什么时候使用哪种方式。如果有大量的逻辑需要封装,那么类方式的实现可能更好。如果我们仅仅是执行一个简单的动作,那么函数的方式或许更好。动动动态态态类类类型型型Python是动态类型的,意味着变量没有固定的类型。事实上,Python中的变量与其他语言中的变量有着很大的不同,尤其是静态类型的语言。变量并不是写有某个值的计算机内

75、存段,它们仅仅是指向对象的“标签”或者“名字”。因此,把一个变量设置为1,然后设置为“一个字符串”,再设置为一个函数是完全可以的。Python的动态类型经常被认为是一个缺点,并且事实上的确会导致复杂性以及难以调试的代码。命名为“a”的变量可以被设置为很多不同的值,开发者或者维护人员需要在代码中跟踪这个名字,以便确保它不会被设置为一个完全不相关的对象。一些准则有助于避免这类问题: 避免为不同的事物使用相同的变量名糟糟糟糕糕糕的的的代代代码码码a = 1a = a stringdef a():pass# Do something好好好的的的代代代码码码count = 1msg = a string

76、def func():pass# Do something使用短小的函数或方法,有助于降低为无关事物使用相同命名的风险,毕竟作用域范围内代码量少了。如果相关的事物有着不同的类型,最好分别使用不同的名字。糟糟糟糕糕糕的的的代代代码码码items = a b c d# 这是一个字符串.items = items.split( )# .变身为列表items = set(items)# .又变为了集合重用名字并不能带来效率的提升:无论如何,赋值都会创建新的对象。然而,随着复杂性的增加,各个赋值语句会被很多行的代码分割开来,包括“if”分支和循环,这会使得要查明某个变量是什么类型变得更加困难。2.1.

77、组组组织织织好好好你你你的的的项项项目目目19Python Guide Documentation, 发发发布布布 0.0.1在一些例如函数式编程的编码实践中,建议绝不要给一个变量重新赋值。在Java中,可以通过 final 关键字来做到禁止重新赋值。Python并没有 final 关键字,因为这会与它的哲学相违背。然而,避免给一个变量赋值超过一次是一个良好的习惯,同时,这也会有助于理解可变类型和不可变类型的概念。可可可变变变与与与不不不可可可变变变类类类型型型Python有两种内置类型或用户自定义类型。可变类型就是那些允许在内容上直接修改的类型。典型的可变类型就是列表和字典:所有列表都有用于

78、修改内容的方法,比如 list.append() 或者 list.pop(),可以直接在列表上进行修改。字典也是一样的。不可变类型并不会提供修改自身内容的方法。比如,设置为整数6的变量x就没有”increment”方法。如果你想计算x+1,你不得不创建另外一个整数并命名。my_list = 1, 2, 3my_list0 = 4print my_list# 4, 2, 3 - 列表本身已经改变x = 6x = x + 1# 等号左边的x已经是另外一个对象,通过id(x)可以知道两种类型在行为上的不同导致的结果就是,可变类型是不“固定的”,因此不能用作字典的键。对于那些本质上会改变的事物应当使用

79、合适的可变类型,对于那些本质上是固定的事物应当使用合适的不可变类型,这会使得代码的目的更加明确。比如,与列表等价的不可变类型是元组,可以通过 (1,2) 来创建。这个元组包含一对不可以直接修改的值,因此可以用作字典的键。Pyhton中的字符串是不可变类型,这可能会让初学者感到吃惊。这意味着,当要从一个字符串的各个组成部分构建字符串时,先把各个部分放到列表(可变类型)里,然后再用join方法粘合起来的方式会更加高效。然而,有一点需要注意的是,列表解析的方式比通过循环调用 append() 来构建列表更好也更快。糟糟糟糕糕糕的的的代代代码码码# 构建一个从0到19连接起来的字符串(比如: 012.

80、1819)nums = for n in range(20):nums += str(n)# 低效且慢print nums较较较好好好的的的代代代码码码# 构建一个从0到19连接起来的字符串(比如: 012.1819)nums = for n in range(20):nums.append(str(n)print .join(nums)# 更加高效优优优雅雅雅的的的代代代码码码# 构建一个从0到19连接起来的字符串(比如: 012.1819)nums = str(n) for n in range(20)print .join(nums)关于字符串最后需要提到的一点:使用 join 并不总是

81、最好的选择。当需要从一定预设数量的字符串构建一个新的字符串时,使用加号操作符实际上更快,但是当类似之前提到的情况或者需要把字符串添加到一个已经存在的字符串上时,使用 join() 应该作为你的首选方式。20Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1foo = foobar = barfoobar = foo + bar# 这种方式挺好foo += ooo# 这种方式可就不好了,你应当采用如下方式:foo = .join(foo, ooo)注注注解解解: 除了 str.join() 和 + 的方

82、式之外,你也可以通过使用 % 格式化操作符来连接预设数量的字符串。然而, PEP 3101,不鼓励使用 % 操作符,而是更提倡使用 str.format() 方法。foo = foobar = barfoobar = %s%s % (foo, bar) # 马马虎虎了foobar = 01.format(foo, bar) # 这样比较好foobar = foobar.format(foo=foo, bar=bar) # 再好不过了第第第三三三方方方依依依赖赖赖运运运行行行部部部件件件进进进一一一步步步阅阅阅读读读 http:/docs.python.org/2/library/ http:/

83、 make_complex(*args):x, y = argsreturn dict(*locals()2.2. 代代代码码码风风风格格格21Python Guide Documentation, 发发发布布布 0.0.1好好好的的的代代代码码码风风风格格格def make_complex(x, y):return x: x, y: y在上述好风格的代码中,x和y可以从调用者那里显式的获取,然后返回一个显式的字典。使用这个函数的开发人员可以通过阅读代码的首行和尾行清楚的知道它是干什么的,而坏风格的代码则无法做到这点。一一一行行行一一一语语语句句句列表解析这种组合语句是被允许和鼓励的,这主要是

84、由于其简洁和富有表现力,尽管如此,把两个不太关联的语句放在同一行却不是一种好的实践方式。坏坏坏的的的代代代码码码风风风格格格print one; print twoif x = 1: print oneif and :# do something好好好的的的代代代码码码风风风格格格print oneprint twoif x = 1:print onecond1 = cond2 = if cond1 and cond2:# do something函函函数数数的的的参参参数数数参数可以通过四种方式来传递给函数。1. 位位位置置置参参参数数数 是强制的且没有默认值。这是最简单的参数形式,这种方式

85、可以被用在很少参数即可表达完整意义的函数中,并且这些参数顺序是很自然的。举个例子,在函数 send(message,recipient) 或者 point(x,y) 中,函数的使用者可以毫不费力的记住这两个函数需要两个参数,以及参数的顺序是什么。在这两个示例中,可以通过使用参数名来调用函数,如果采用这种方式,参数的顺序是可以交换的,调用方式为 send(recipient=World, message=Hello) 以及 point(y=2,x=1) ,但是与直接调用 send(Hello, World) 和 point(1, 2) 相比,这会降低可读性,同时也造成了不必要的冗长。2. 关关关

86、键键键字字字参参参数数数 不是强制的且可以有默认值。它们通常被用于发送给函数的可选参数。当函数有多于两个或三个位置参数时,函数签名会变得相对难记,这时,使用带有默认值的关键字参数会有帮助的多。例如,更加完整的 send 函数可能被定义为 send(message, to, cc=None, bcc=None) 。这里的 cc 和 bcc 是可选的,并且,在没有被传递其他值时,会被赋值为None。在Python中,调用带有关键字参数的函数有多种方式,比如,可以按照函数定义时参数的顺序来调用,这时不需要显式的命名参数,就像 send(Hello, World, Cthulhu,God) 中一样,发

87、送秘密抄送给上帝。同样,也可以用命名参数的方式来按其他顺序调用,22Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1就像 send(Hello again, World, bcc=God, cc=Cthulhu) 。除非有很重要的原因,否则上述两种方式最好避免使用,而应该按照最接近函数定义的语法方式来调用:send(Hello, World, cc=Cthulhu, bcc=God) 。作为附注,参见 YAGNI 准则,通常来说,移除那些似乎永远用不到但为了“以防万一”而添加的可选参数(以及它在函数

88、内的逻辑部分),要比需要时再添加新的可选参数以及其逻辑要困难的多。(译者注:也就是说,如无必要,不必预留不太可能用到的可选参数)3. 任任任意意意参参参数数数列列列表表表 是传递给函数参数的第三种方式。如果函数的意图可以通过一个包含有数目可扩展的位置参数的函数签名表达出来,那么,可以定义一个使用了*args 参数的函数。在函数体内, args会是一个剩余位置参数组成的元组。例如, 可以使用每个接收者作为参数来调用 send(message,*args) : send(Hello, God, Mom, Cthulhu) ,在函数体内 args 等同于 (God,Mom, Cthulhu) 。然而

89、,这种构造有一些缺点,使用时应当谨慎。如果一个函数接收一组具有相同属性的参数,那么把函数定义成接收列表形式或者任意序列形式参数的方式会更加清晰。此例而言,如果send 有多个接收者,最好显式的把它定义为: send(message, recipients) ,并且以send(Hello, God, Mom, Cthulhu) 方式调用。这样,函数使用者可以以预先定义好的列表形式来操作一组接收者,同时也打开了传递任何序列的可能性,包括无法解包为其他序列的迭代器。4. 关关关键键键字字字参参参数数数字字字典典典 是最后一种函数传递参数的方式。如果函数需要一系列未确定的命名参数,可以使用*kwarg

90、s 构造。在函数体内, kwargs 是一个由所有尚未被函数签名中关键字参数捕获的其他命名参数的字典。与 任意数目参数列表 中一样,也必须谨慎使用这种方式,原因也是相似的:这种强力的技术应该在必要的时候才使用,如果存在更简单更清晰的方式即可满足函数的意图,那么应该避免使用 关键字参数字典 这种方式。哪些参数作为位置参数,哪些参数作为可选的关键字参数,是否使用传递任意数目参数的高级技术,这都是由编写函数的开发者来决定的。如果明智的采用上述建议,完全有可能愉快的写出符合下列条件的函数: 易于阅读(函数名和参数无需过多解释) 易于修改(添加新的关键字参数不会破坏代码的其他部分)避避避免免免魔魔魔法法

91、法方方方法法法作为黑客的强力的工具,Python自带了非常丰富的钩子和工具,允许你完成几乎任何奇技淫巧的事情。例如,它可以完成以下任何一件事: 改变对象的创建和初始化方式 改变Python解释器导入模块的方式 在Python中嵌入C代码(如果需要的话,建议这么做)然而,所有这些选择都有许多缺点,所以使用最为直接的方式来达到你的目的总会更好。最为主要的缺点是使用这些构造方式严重影响了可读性。许多代码分析工具,例如pylint或者pyflakes将无法解析这些“魔幻的”代码。我们认为Python开发者应该了解这些几乎无限的可能性,因为这会给你灌输自信,让你觉得没有不可逾越的难题。然而,知道怎么使用

92、以及明确何时 不不不 去使用它们却非常重要。就像功夫大师一样,一个Pythonista知道如何用一根指头杀人,然而却永远不会这么做。2.2. 代代代码码码风风风格格格23Python Guide Documentation, 发发发布布布 0.0.1我我我们们们都都都是是是负负负责责责的的的用用用户户户如上所见,Python允许很多技巧,但是其中一些具有潜在的危险性。一个比较好的例子是客户端代码可以重写对象的属性和方法:在Python中,没有“private”关键字。这是Python的哲学,与像Java这样具有高度防御性的语言不同,高防御性语言会提供许多机制来阻止任何的误用,而Python会通

93、过表明:我们都是负责的用户来达到这点。这并不意味着,属性不能被认为是私有的,抑或Python无法进行合适的封装。相反,Python并不依赖于开发者在自身代码和其他人的代码之间竖立坚固的墙来达到隔离,Python社区更倾向于依赖一系列的惯例来表明这些元素不应当被直接访问。对于私有属性,主要的惯例和实现细节是对所有“内部的元素”使用下划线前缀。如果客户端代码破坏这个规则,并且访问这些标记的元素,遇到的任何不正确行为或者问题都应当由客户端代码负责。我们鼓励慷慨的使用这些惯例:任何不计划被客户端代码使用的方法或者属性应当使用下划线作为前缀。这样可以确保更好的责任分离以及对已有代码更容易的修改;把私有属

94、性公有化总是可行的,反之,把公有属性私有化则困难的多。返返返回回回值值值随着函数复杂性的增长,在函数体内使用多个返回语句变得很常见。然而,为了保持函数意图明确以及维持足以接受的可读性,更倾向于避免从函数体的多个出口点返回有意义的值。在一个函数中返回值主要有两种情况:一种是函数正常处理完毕返回结果,另一种是返回错误情况,以便说明由于错误的输入参数或者其他原因,进而导致函数无法完成计算或任务。如果在第二种情况下你不希望抛出异常,那么应当返回一个None或者False值来表明函数无法正常处理。这种情况下,最好在检测到不正确的上下文时尽早返回。这样有助于函数结构的扁平:返回语句(由于错误而返回)之后的

95、代码可以认为是满足后续计算函数结果的情形。函数中往往会有多个这样的返回语句(由于错误而返回)。然而,当一个函数在正常路径上有多个主要的退出点时,会导致难以调试返回结果,所以如果可能,应当保留单个退出点。这将有助于提取一些公共的代码路径,并且如果有多个退出点也说明函数很有可能需要重构。def complex_function(a, b, c):if not a:return None# 抛出异常可能会更好if not b:return None# 抛出异常可能会更好# 尝试从a, b和c中计算x的复杂代码# 如果成功,暂时先不返回xif not x:# 计算x的其他方式return x# 返回值

96、x有单一的退出点有助于代码的维护惯惯惯用用用语语语法法法编程习惯,简而言之就是写代码的 方式 。在 c2 和 Stack Overflow 上有着对编程习惯广泛的讨论。惯用的Python代码通常可以称为 Pythonic 的代码。尽管通常有一种(当然,最好也只有一种)显而易见的方式来写惯用代码,但是对于Python初学者来说,如何写出符合语言习惯的Python代码却并不那么明显。所以,好的编程习惯必须主动学习才能获得。一些通用的Python惯用语法如下:24Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.

97、0.1解解解包包包如果你知道列表或者元组的长度,你可以通过解包来给其中的元素分配名字。例如, enumerate() 会为列表中的元素生成一个二元组:for index, item in enumerate(some_list):# do something with index and item你也可以使用这种方式来交换变量:a, b = b, a嵌套的部分也可以解包:a, (b, c) = 1, (2, 3)在Python 3中,通过 PEP 3132 引入了一种新方法来扩展解包方式:a,*rest = 1, 2, 3# a = 1, rest = 2, 3a,*middle, c = 1

98、, 2, 3, 4# a = 1, middle = 2, 3, c = 4创创创建建建可可可忽忽忽略略略的的的变变变量量量如果你需要把某值赋给变量(例如,在 解包 中),但是又不会真正用到这个变量,那么可以使用 _ :filename = foobar.txtbasename, _, ext = filename.rpartition(.)注注注解解解: 许多Python风格指南建议使用单个下滑线 “_” 来处理那些用不到的变量,而不是这里建议的双下划线“_” 。这种方式的问题在于 “_” 通常会被用作 gettext() 函数的别名,同时,在交互式环境中,单下划线往往保存着最后一次操作的结

99、果值。而双下划线与单下划线一样清晰方便,且消除了这两种情形下意外干扰的风险。创创创建建建长长长度度度为为为N的的的且且且由由由相相相同同同元元元素素素组组组成成成的的的列列列表表表使用Python列表的*操作符:four_nones = None*4创创创建建建长长长度度度为为为N且且且元元元素素素为为为列列列表表表的的的列列列表表表由于列表是可变的,*操作符(如上)会创建一个包含有N个指向 同一 列表引用的列表,这种方式并不是我们想要的。这种情况下,我们使用列表解析:four_lists = for _ in xrange(4)注意:在Python 3中要使用range()代替xrange(

100、)2.2. 代代代码码码风风风格格格25Python Guide Documentation, 发发发布布布 0.0.1从从从列列列表表表创创创建建建字字字符符符串串串创建字符串的通用惯例是在空字符串上调用方法 str.join() 。letters = s, p, a, mword = .join(letters)这种方式会给变量 word 赋值为“spam”。这种惯用方式适用于列表和元组。在在在聚聚聚合合合集集集中中中搜搜搜索索索元元元素素素有时候我们需要在聚合集中进行查找。这里我们来看看两种结构的查找方式:列表和集合。代码示例:s = set(s, p, a, m)l = s, p, a

101、, mdef lookup_set(s):return s in sdef lookup_list(l):return s in l尽管两个函数看起来完全一样,但是由于 look_set 利用了Python集合属于哈希表的特性,二者之间的性能差异极大。为了确定一个元素是否在列表中,Python不得不遍历每一个元素,直到找到匹配的元素为止。这是很耗时的操作,尤其是列表很长的时候。另一方面,在集合中,元素的哈希值会直接告诉Python去哪里查找匹配的元素。所以即使集合再大,也可以很快的完成查找。字典中的查找方式也类似集合。更多信息请参见 StackOverflow 。如果想知道各种常用操作在这些数

102、据结构上耗费时间的详细信息,请参见 此页 。由于性能上的差异,以下情形使用集合或者字典来代替列表是个不错的主意: 聚合集包含有大量的元素 需要不断重复的在聚合集中搜索元素 没有重复的元素对于一些小的聚合集,或者是不需要进行频繁搜索的聚合集,创建哈希表所花费的时间和内存,往往会比由于搜索速度提升而节省出的时间更多。Python之之之禅禅禅因 PEP 20 为人熟知,这是Python设计的指导准则。翻译 在此 。 import thisPython之禅, by Tim Peters优美胜于丑陋,明晰胜于隐晦。简单胜于复杂,复杂胜于繁芜。扁平胜于嵌套,稀疏胜于密集。可读性很重要。虽然实用性比纯粹性更

103、重要,但特例并不足以把规则破坏掉。错误状态永远不要忽略,除非你明确地保持沉默,直面多义,永不臆断。26Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1最佳的途径只有一条,然而他并非显而易见-谁叫你不是荷兰人?置之不理或许会比慌忙应对要好,然而现在动手远比束手无策更好。难以解读的实现不会是个好主意,容易解读的或许才是。名字空间就是个顶呱呱好的主意。让我们想出更多的好主意!这里有一些符合Python风格的例子,参见 这些幻灯片来自Python用户组 。PEP 8PEP 8 是Python事实上的代码风格

104、指南。pep8.org 上有一份高质量且易读的PEP 8版本。强烈建议阅读这份指南。整个Python社区都尽最大努力遵守这份文档中提及的指导。一些项目可能会随着时间推移逐渐偏离其指导,而另外一些则会 改善其中的建议 。 总之,确保你的代码遵循PEP 8通常来说是个不错的主意,并且与其他开发者合作时,这也有助于代码风格的统一。有一个命令行工具 pep8 ,可以帮助你检查代码是否符合规范。在终端执行下面的命令来安装:$ pip install pep8然后在需要检查的文件上运行这个命令,就可以得到检测报告:$ pep8 optparse.pyoptparse.py:69:11: E401 mult

105、iple imports on one lineoptparse.py:77:1: E302 expected 2 blank lines, found 1optparse.py:88:5: E301 expected 1 blank line, found 0optparse.py:222:34: W602 deprecated form of raising exceptionoptparse.py:347:31: E211 whitespace before (optparse.py:357:17: E201 whitespace after optparse.py:472:29: E2

106、21 multiple spaces before operatoroptparse.py:544:21: W601 .has_key() is deprecated, use in工具 autopep8 可以自动把代码重新格式化到符合PEP 8风格。安装方式如下:$ pip install autopep8可以用这个工具来直接格式化并修改文件:$ autopep8 -in-place optparse.py如果除去 -in-place 标志,它会把格式化后的代码直接输出到终端,以便查看。 -aggressive 标志会进行更大的修改,可以通过多次使用这个标志来达到更好的格式化效果。约约约定定

107、定你应当按照本节的约定,以便你的代码更容易阅读。2.2. 代代代码码码风风风格格格27Python Guide Documentation, 发发发布布布 0.0.1检检检查查查变变变量量量是是是否否否等等等于于于常常常量量量对于一个值,你并不需要显示地把它与True、None或者0进行比较 - 只需要把它放到if语句中即可。参见Truth Value Testing 了解哪些值可以认为是false。坏坏坏的的的代代代码码码风风风格格格:if attr = True:print True!if attr = None:print attr is None!好好好的的的代代代码码码风风风格格格:

108、# 只需检查值即可if attr:print attr is truthy!# 或者检查值的相反情况if not attr:print attr is falsey!# 又或者,由于None可以被认为是false,可以显示的检查一下if attr is None:print attr is None!访访访问问问字字字典典典元元元素素素不要使用 dict.has_key() 方法。取而代之,使用 x in d 的语法形式或者给 dict.get() 传递一个默认值。坏坏坏的的的代代代码码码风风风格格格:d = hello: worldif d.has_key(hello):print dhel

109、lo# 输出 worldelse:print default_value好好好的的的代代代码码码风风风格格格:d = hello: worldprint d.get(hello, default_value) # 输出 worldprint d.get(thingy, default_value) # 输出 default_value# 或者:if hello in d:print dhello操操操作作作列列列表表表的的的简简简便便便方方方式式式列表解析 提供了一种强大简洁的方式来操作列表。此外,map() 和 filter() 函数使用了不同却更加简洁的语法。坏坏坏的的的代代代码码码风风风

110、格格格:28Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1# 过滤大于4的元素a = 3, 4, 5b = for i in a:if i 4:b.append(i)好好好的的的代代代码码码风风风格格格:a = 3, 4, 5b = i for i in a if i 4# 或者:b = filter(lambda x: x 4, a)坏坏坏的的的代代代码码码风风风格格格:# 对每个列表元素加3a = 3, 4, 5for i in range(len(a):ai += 3好好好的的的代代代码码码

111、风风风格格格:a = 3, 4, 5a = i + 3 for i in a# 或者:a = map(lambda i: i + 3, a)使用 enumerate() 来获取元素在列表中的位置。a = 3, 4, 5for i, item in enumerate(a):print i, item# 输出# 0 3# 1 4# 2 5enumerate() 函数相对于手动计数有着更好的可读性,而且有助于迭代器的优化。读读读取取取文文文件件件使用 with open 语法来读取文件,这种方式会自动关闭文件。坏坏坏的的的代代代码码码风风风格格格:f = open(file.txt)a = f.r

112、ead()print af.close()好好好的的的代代代码码码风风风格格格:with open(file.txt) as f:for line in f:print linewith 语句是一种更好的选择,因为这种方式会确保文件的关闭,即使在 with 代码块中抛出异常也能正确处理。2.2. 代代代码码码风风风格格格29Python Guide Documentation, 发发发布布布 0.0.1延延延续续续代代代码码码行行行当代码的逻辑行长度超过限制时,需要把代码分割成逻辑上关联的几行。如果一行代码的最后一个字符是反斜杠,那么Python解释器会自动把后续的行连接起来。在一些情况下,这

113、种做法很有用,但是通常应当避免这种方式,因为这种处理方式比较脆弱:行末尾反斜杠之后的空白会破坏代码并且导致一些无法预期的结果。更好的解决方案是使用括号。如果一行开头有左括号,但是行末却没有相应的右括号,Python解释器会把下一行连接起来,直到遇到关闭的右括号。对于大括号和方括号也有类似的行为。坏坏坏的的的代代代码码码风风风格格格:my_very_big_string = For a long time I used to go to bed early. Sometimes, when I had put out my candle, my eyes would close so quick

114、ly that I had not even time to say “Im going to sleep.”from some.deep.module.inside.a.module import a_nice_function, another_nice_function, yet_another_nice_function好好好的的的代代代码码码风风风格格格:my_very_big_string = (For a long time I used to go to bed early. Sometimes, when I had put out my candle, my eyes wo

115、uld close so quickly that I had not even time to say “Im going to sleep.”)from some.deep.module.inside.a.module import (a_nice_function, another_nice_function, yet_another_nice_function)然而,多半情况下,当不得不分割一行很长的代码时,往往预示着你同时尝试完成的功能太多,这有可能会妨碍可读性。阅阅阅读读读优优优秀秀秀代代代码码码Python设计背后的核心理念之一就是创建高可读性的代码。这种设计背后的动机很简单:P

116、ython程序员首要做的事就是阅读代码。成为优秀Python开发者的秘诀之一就是读代码,了解代码,然后深入理解优秀的代码。译译译者者者注注注 :下面是Youtube的视频,请自备梯子。优秀的代码都会遵循 代码风格 中罗列的指导规范,并且会尽可能向其读者表达出清晰简洁的意图。下面罗列一些推荐阅读的Python项目。这里的每一个项目都是Python编码的模范之作。 Howdoi 是一个搜索工具,采用Python开发。 Flask 是基于Werkzeug和Jinja2的Python微框架。其目标:为实现构想而进行快速开发。 Diamond 是一个Python守护程序,可以搜集监测数据并发送到 Gra

117、phite 或者其他后端。目前可以搜集包括CPU、内存、网络、IO设备、负载以及磁盘在内的相关数据。另外,它还提供了API来实现定制化的搜集器,可以从几乎任何来源搜集数据。 Werkzeug 开始只是供WSGI应用使用的一些简单的工具集合,后面逐渐发展成为高级WSGI工具模块中的一员。其中包括了强大的调试器、特性齐全的请求/响应对象、处理实体标签的HTTP工具、缓存控制头、HTTP日期、Cookie处理、文件上传、强大的URL路由系统以及一大堆社区贡献的其他模块。 Requests 是一个基于Apache2许可证的HTTP库,采用Python开发,非常人性化。30Chapter 2. 写写写出

118、出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1 Tablib 是一个与格式无关、实现数据集表格化输出的库,采用Python开发。待待待处处处理理理增加上述每个项目里代码的典型示例。解释为什么这是优秀的代码。可以使用一些较为复杂的示例。待待待处处处理理理讲述一些可以快速确定数据结构、算法并确定代码实现什么功能的技术。文文文档档档无论是项目文档还是代码文档,可读性都是Python开发人员重点关注的一方面。遵守一些简单的最佳实践可以为你和他人节省出一大堆时间来。项项项目目目文文文档档档README 文件在项目根目录下,主要给出项目维

119、护者以及用户的常规信息。此文件最好是使用纯文本或者一些容易阅读的标记文本来编写,例如使用 reStructuredText 或者Markdown。文件中应当包含几行内容来说明本项目或者本库主要用来干什么(要假设用户对此项目一无所知)、软件源代码的URL以及一些基本的信用信息。这个文件可以说是代码阅读人员的主要入口。INSTALL 文件在Python项目中不是那么的必要。安装指导通常只是一个命令,比如 pip installmodule 或者 python setup.py install ,可以直接添加到 README 文件中。LICENSE 文件应该 总是 存在,并且需要指明软件在什么许可证

120、下对公众可用。TODO 文件或者是 README 中的 TODO 章节应当列出代码的开发计划。CHANGELOG 文件或者 README 中的 CHNANGELOG 章节应当为最新版本的代码基变更作出一个简短的说明。项项项目目目发发发布布布依项目不同,通常你的文档可能会由以下全部或者部分的内容构成: 简介 主要是对该项目产品可以干什么作出一个非常简短的说明,可以使用一个或者两个极其简单的例子。这可以说是对你项目进行一个30秒的推销。 指南 应当更加详细地展示一些初级的案例。读者可以一步一步根据案例来搭建一个可工作的原型。 API参考 通常直接由代码来生成(参见 docstrings )。其中会

121、列出所有公开可用的接口、参数以及返回值。 开发文档 主要是为潜在的贡献者人员提供。其中会包括代码约定以及项目的常规设计策略等。SphinxSphinx 无疑是最为流行的Python文档工具。 赶赶赶紧紧紧去去去使使使用用用吧吧吧。 它会把 reStructuredText 标记语言转换为各种格式的输出,包括HTML、LaTeX(用于可打印的PDF)、man手册以及普通文本。2.4. 文文文档档档31Python Guide Documentation, 发发发布布布 0.0.1网上还有一个 非非非常常常好好好用用用 且 免免免费费费 的 Sphinx 文档托管网站: Read The Docs

122、 。赶紧去使用吧。通过配置它的提交钩子到你的源码仓库,可以实现自动化构建你的文档。运运运行 Sphinx 时,会自动导入你的代码,并利用Python的内省机制提取出代码中的函数、方法以及类签名。同时还会提取出相应的文档字符串,并编译成结构良好又易于阅读的项目文档。注注注解解解: Sphinx以由API生成文档而闻名,但是对于常规项目文档的生成也可以完成的很好。本文档就是使用Sphinx 构建并托管于 Read The Docs 上。reStructuredText大部分的Python文档使用 reStructuredText 来编写。这种标记语言就像是内建了各种可选扩展的Markdown。re

123、StructuredText Primer 和 reStructuredText Quick Reference 可以帮助你熟悉其语法。译译译者者者注注注: 网上有中文教程,请自行搜索。代代代码码码文文文档档档建建建议议议注释可以阐明代码,它们主要用来让代码更加容易理解。在Python中,注释以 # 开头。 在Python中, 文档字符串(docstrings) 描述了模块、类以及函数:def square_and_rooter(x):返回自身乘以自身后的平方根.通常可以参照 PEP 8#comments (Python风格指南)中的注释那一节。关于文档字符串的更多信息可以在PEP 0257#

124、specification (文档字符串约定指南)中找到。注注注释释释代代代码码码片片片段段段不要使用三引号字符串来注释代码 。这种方式并不是一个好的实践,因为类似grep这种面向行操作的命令行工具,是无法知晓那部分代码已失效的。更好的方式是确保正确的缩进,并在每个注释行前添加 # 。你使用的编辑器说不定可以很容易的完成这种功能,所以学习下如何注释/取消注释是很值得的。文文文档档档字字字符符符串串串与与与魔魔魔法法法一些工具会使用文档字符串来实现一些不仅限于文档的行为,比如单元测试的逻辑。这看上去很不错,但是你不会因为“这里就是这么做的”而永远不出错。Sphinx 会把你的文档字符串解析为re

125、StructuredText,然后渲染成HTML,这就可以很方便的把示例代码嵌入到文档项目中。另外, Doctest 会读取所有格式为Python命令行输出样式(以”为前缀)的文档字符串,然后执行这部分文档内容,检测命令的结果是否匹配紧接着的下一行内容。开发人员可以利用示例代码和函数使用说明一起来注释源码,顺便还可以确保代码被测试通过。def my_function(a, b): my_function(2, 3)6 my_function(a, 3)aaa32Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布

126、0.0.1return a*b文文文档档档字字字符符符串串串与与与块块块注注注释释释二者并非不可交换。对于一个函数或者类,开头的注释块是开发人员的笔记说明。文档字符串则描述了函数或者类进行的 操作 。# 这个函数会由于某些原因降低程序的运行速度def square_and_rooter(x):返回自身乘以自身后的平方根.与块注释不同,文档字符串内建于Python语言自身。这意味着在运行时你可以使用Python强大的内省能力来访问文档字符串,相比而言,注释则会被优化掉。几乎每一个Python对象都可以从 _doc_ 属性或者内建的help() 函数来访问文档字符串。块注释通常用于解释一段代码是做

127、什么的,或者阐述一个算法,而文档字符串更倾向于向别人解释你的代码中的某个函数如何使用以及一个函数、类或模块的主要目的是什么。编编编写写写文文文档档档字字字符符符串串串根据所写函数、方法或类的复杂性,有时候单行文档字符串非常适用。以下是一个非常鲜明的例子:def add(a, b):把两个数字相加,返回结果return a + b文档字符串应该以一种非常易懂的方式来描述函数。对于一些不重要的函数或者类,简单的把函数签名(比如: add(a, b) - result )嵌入到文档字符串完全没必要。因为如果需要的话,使用Python的 inspect 模块可以很容易找到这些信息,而且通过阅读代码也可

128、以很容易明白。然而,在更大更复杂的项目中,最好还是对一个函数给出足够多的信息:它做了什么、有可能抛出什么异常、返回什么或者一些参数的相关细节。Numpy项目使用了一种流行的文档风格来给出代码更详细的信息,称为 Numpy风格 的文档字符串。尽管这种注释风格会比之前的示例占用更多行,但是也让开发人员可以为一个方法、函数或类提供更多的信息:def random_number_generator(arg1, arg2):Summary line.Extended description of function.Parameters-arg1 : intDescription of arg1arg2

129、: strDescription of arg2Returns-intDescription of return value2.4. 文文文档档档33Python Guide Documentation, 发发发布布布 0.0.1return 42插件 sphinx.ext.napoleon 可以让Sphinx解析这种风格的文档字符串,方便你把Numpy风格的文档字符串包含到项目中。最后,采用什么风格编写文档字符串并不重要,它们的目的都是为那些需要阅读或者修改你代码的人而服务的。只要这些文档是正确的、可以理解的并且你得到了想要知道的,那么赋予它的使命就算完成了。如果还想对文档字符进一步的了解,

130、参考 PEP 257其其其他他他工工工具具具你可能会在其他地方看到这些工具。参见 Sphinx 。Pycco Pycco是一个“文学编程风格的文档生成器”,是node.js里 Docco 的移植。它可以把代码转化成代码与文档并排展现的HTML格式。Ronn Ronn可以构建Unix的man手册。它可以把人类可读的文本转换为用于终端显示的roff格式以及用于Web的HTML格式。Epydoc Epydoc已经停止开发。使用 Sphinx 替代吧。MkDocs MkDocs是一个快速简单的静态网站生成器,致力于使用Markdown来构建项目文档。测测测试试试你你你的的的代代代码码码对自己的代码进行

131、测试是非常重要的一步。同时编写测试代码和实际运行的代码是一个非常好的习惯。合理利用这种方法可以帮助你更加精确的定位代码功能,并构建出一个更加解耦的架构。测试中一些通用的准则: 一个测试单元应当聚焦于一个很小的功能并证明其实现的正确性。 每一个测试单元必须保持完全独立。保证既可以单独运行,又可以集成在测试套件中运行,而不必考虑其调用的顺序。这个规则暗含这样的意思:每个测试载入的数据集必须是全新的,并且完成测试后需要清理这些数据集。这通常通过方法 setUp() 和 tearDown() 来实现。 尽可能的使得测试集可以快速运行。如果单单一个测试就需要运行几毫秒的话,不仅会降低开发速度,也可能无法

132、按照需要的那样尽可能频繁的运行测试。在某些情况下,测试集由于工作在复杂的数据结构上,且每次都要载入这些数据结构,所以测试无法快速运行。这时,可以把这种比较重量级的测试集放在单独的测试套件中,该测试套件通过计划任务来运行,而其他测试集则可以尽可能频繁的运行。 学习使用工具,并学习如何运行一个单独的测试或者测试用例。这样,当在模块中开发一个函数时,可以频繁的运行这个函数的测试,理想的方式是每次保存代码时自动运行对应的测试。 在每次进行编码任务前运行全套的测试套件,完成此次编码任务后再次运行。这会让你更确信自己的编码没有对代码的其他部分造成任何破坏。 通过实现钩子,把代码推送到共享仓库之前自动运行所

133、有测试集是一个好的主意。 如果你正在进行开发中,并且由于其他原因不得不打断目前的开发工作,那么,对接下来要开发的部分编写一个损坏的单元测试是个不错的主意。当你回来继续工作时,你可以有个类似指针一样的东西告诉你目前工作在哪个地方,这样就可以快速回归开发状态。34Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1 调试代码的第一步:编写一个新的测试来精确的暴露出BUG。尽管不可能总这样做,但是,那些捕获BUG的测试集可以说是项目中最具有价值的一部分。 给测试函数命名一个长的具有描述性的名字。这里的代码风格

134、与实际运行的代码略微有一些不同,对于实际运行的项目代码,我们更倾向于短命名。原因在于,测试函数从不会被显示的调用。在实际运行的代码中 square() 或者 sqr() 都是可以的,但是在测试代码中,你应该命名为test_square_of_number_2() 、 test_square_negative_number() 。这些函数名会在测试失败时显示,所以应当尽可能的具有描述性。 当出现错误或者不得不进行改变时,如果有一个好的测试集,你和其他维护者就可以大量的依赖测试套件来修复问题所在,或者修改给定的行为。因此,相比于实际运行的代码,测试代码被阅读的次数至少会与其一样多,甚至更多。这种情

135、况下,目的不清晰的单元测试用处并不大。 测试代码的另外一个用途是作为新开发人员的入门介绍。当有人不得不在代码基上进行工作时,运行并阅读相关的测试代码通常是他们开始的最好方式。他们可以发现热点所在、哪些地方是难点以及一些边边角角的情形。如果他们想添加某个功能,第一步要做的就是添加一个测试,通过这种方法,确保新功能不再是一个没有嵌入到接口中的工作路径。基基基础础础知知知识识识单单单元元元测测测试试试unittest 是Python标准库内置的测试模块。如果使用过JUnit/nUint/CppUnit系列工具中的任何一个,你会发现这个模块的API非常熟悉。可以通过实现 unittest.TestCa

136、se 的子类来完成创建测试用例。import unittestdef fun(x):return x + 1class MyTest(unittest.TestCase):def test(self):self.assertEqual(fun(3), 4)Python 2.7 标准库中的单元测试模块 包含自己的测试发现机制。文文文档档档测测测试试试doctest 模块会在文档字符串中搜索看起来像交互式Python会话的文本片段,然后执行这些会话,以确认是否可以如展示的那样工作。文档测试与单元测试有着不同的使用情形:它们通常很少详细的描述,不会捕捉特殊的情况或者不明显的回归Bug。它们的主要用途

137、是作为表述性文档来描述模块及其组成的主要部分。然而,每次完整运行测试套件时,文档测试也应当自动运行。函数中简单的文档测试:def square(x):Return the square of x. square(2)4 square(-2)42.5. 测测测试试试你你你的的的代代代码码码35Python Guide Documentation, 发发发布布布 0.0.1return x*xif _name_ = _main_:import doctestdoctest.testmod()当以 python module.py 方式在命令行中运行这个模块时,文档测试就会运行,并且,如果没有按照文

138、档字符串中描述的行为执行,会发出提示。工工工具具具py.testpy.test是Python标准库中unittest模块的可选替代。$ pip install pytest尽管是一个特性齐全、可扩展的测试工具,但是它具有简单的语法。创建一个测试套件如同编写一个只包含有几个函数的模块一样简单:# test_sample.py的内容def func(x):return x + 1def test_answer():assert func(3) = 5然后运行 py.test 命令$ py.test= test session starts =platform darwin - Python 2.7

139、.1 - pytest-2.2.1collecting . collected 1 itemstest_sample.py F= FAILURES =_ test_answer _def test_answer():assert func(3) = 5Eassert 4 = 5E+where 4 = func(3)test_sample.py:5: AssertionError= 1 failed in 0.02 seconds =与unittest模块相比,同样的功能,py.test需要更少的工作。Nosenose扩展了unittest来使得测试更加容易。$ pip install nose

140、36Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1nose提供了自动发现测试集的功能,避免了人工创建测试套件的麻烦。同时也提供了大量的插件来支持兼容xUnit的测试输出、覆盖率报告以及测验选择等特性。nosetoxtox是一个管理自动测试所需环境以及配置多解释器测试的工具。$ pip install toxtox使用简单的ini格式配置文件,以便允许你配置复杂的多参数测试模型。toxUnittest2unittest2是Python 2.7中unittest模块的移植,该模块拥有增强的API以及更

141、好的断言,超越了之前Python中对应的模块。如果你使用Python 2.6或者更低的版本,可以通过pip来安装:$ pip install unittest2可以采用unittest名自来引入该模块,这样,将来移植代码到模块的新版本时会更加容易。import unittest2 as unittestclass MyTest(unittest.TestCase):.采用这种方式,如果需要转换到新版本的Python,并且不再需要unittest2模块时,可以简单的在测试模块中修改引入部分,而不需要修改其他的代码。mockunittest.mock 是Python中用于测试的一个库。在Pytho

142、n 3.3中已经成为了 标准库 的一部分。对于旧版本的Python:$ pip install mock该库可以用模拟对象来替换待测试系统的一部分,你会从中知晓它们是如何被使用的。例如,你可以给一个方法打猴子补丁:from mock import MagicMockthing = ProductionClass()thing.method = MagicMock(return_value=3)thing.method(3, 4, 5, key=value)thing.method.assert_called_with(3, 4, 5, key=value)使用 patch 装饰器在待测试的模块

143、中模拟类或者对象。在下述示例中,采用总是返回相同结果(仅限于该测试期间)的模拟对象来替代外部搜索系统。2.5. 测测测试试试你你你的的的代代代码码码37Python Guide Documentation, 发发发布布布 0.0.1def mock_search(self):class MockSearchQuerySet(SearchQuerySet):def _iter_(self):return iter(foo, bar, baz)return MockSearchQuerySet()# 这里的SearchForm指的是myapp中导入的类引用,并不是SearchFrom本身被引入前的

144、所在mock.patch(myapp.SearchForm.search, mock_search)def test_new_watchlist_activities(self):# get_search_results进行搜索操作并对结果进行迭代self.assertEqual(len(myapp.get_search_results(q=fish), 3)Mock还有许多其他的配置方式来控制其行为。日日日志志志自Python 2.3之后,logging 模块已经成为标准库的一部分。PEP 282 里进对此行了简单的介绍。 但该文档是出了名的难读,唯有 Python基础日志教程 相对容易学习

145、。日志主要有两个目的: 诊诊诊断断断性性性日日日志志志 记录应用操作的相关事件。如果用户引入日志模块用来报告错误,那么就可以通过在日志中搜索上下文来获取相关错误信息。 审审审计计计性性性日日日志志志 记录用于商业分析的事件。用户进行的事务可以被提取出来,然后与另外的用户详细信息组合形成报告,或者用来进行优化,以达到更好的业务目标。日日日志志志还还还是是是Print输输输出出出?只有在一种情况下 print 相比于日志是一个更好的选择:在命令行应用下展示帮助信息时。其他情况下,日志毫无疑问是更好的选择,原因如下: 每一个日志事件创建的 日志记录 包含有可读的诊断信息,例如文件名、完整路径、函数以

146、及日志事件发生的行号。 除非你过滤掉所引用模块中的日志事件,否则它会被根logger自动访问,进而输出到应用程序本身的日志流中。 日 志 可 以 通 过 使 用logging.Logger.setLevel()或 者 通 过 设 置 属 性logging.Logger.disabled 为 True 选择性不显示。函函函数数数库库库中中中的的的日日日志志志库开发中的日志配置 是 Python日志教程 中的一部分。由于是 用用用户户户 而不是库本身来说明当日志事件出现时究竟发生了什么,所以脑子里要不断重复下警告:注注注解解解: 强烈建议除NullHandler外不要添加任何其他handler到所

147、写库的日志logger中。当在一个库中初始化loggers时,最佳实践方法是仅使用全局变量 _name_ 来创建这些loggers:logging模块使用点号来创建层次性的loggers,所以,使用 _name_ 可以确保不会有名字冲突。如下是来自 requests源码 的最佳实践示例 可以把这段代码放到你的 _init_.py 文件中:38Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1# 设置默认的日志处理模块,避免产生 No handler found 警告。import loggingtry

148、:# Python 2.7+from logging import NullHandlerexcept ImportError:class NullHandler(logging.Handler):def emit(self, record):passlogging.getLogger(_name_).addHandler(NullHandler()应应应用用用程程程序序序中中中的的的日日日志志志The Twelve-Factor App 是一份应用开发最佳实践的权威性参考,其中包含了一节 日志最佳实践 。它重点提倡把日志事件当作事件流来对待,然后把事件流发送到标准输出,以便被应用环境进行处理

149、。至少有三种方式来配置logger: 使使使用用用INI格格格式式式的的的文文文件件件: 优优优点点点: 通过使用函数 logging.config.listen() 监听socket可以在程序运行时更新配置。 缺缺缺点点点: 相比在代码中配置logger,可控性较弱(比如 利用子类定制filters或者loggers) 使使使用用用字字字典典典或或或者者者JSON格格格式式式的的的文文文件件件: 优优优点点点: 除了能在程序运行时更新外,还可以通过 json 模块载入文件来更新,该模块自Python2.6进入标准库。 缺缺缺点点点: 相比在代码中配置logger,可控性较弱。 使使使用用用代

150、代代码码码: 优优优点点点: 对配置可进行完全控制。 缺缺缺点点点: 修改配置需要改动源代码。使使使用用用INI文文文件件件配配配置置置的的的例例例子子子这里我们把配置文件叫做 logging_config.ini 。该文件格式的更多细节可参考 Python日志教程 中的 配置日志 一节。loggerskeys=roothandlerskeys=stream_handlerformatterskeys=formatterlogger_rootlevel=DEBUGhandlers=stream_handlerhandler_stream_handlerclass=StreamHandlerle

151、vel=DEBUGformatter=formatter2.6. 日日日志志志39Python Guide Documentation, 发发发布布布 0.0.1args=(sys.stderr,)formatter_formatterformat=%(asctime)s %(name)-12s %(levelname)-8s %(message)s然后,在代码中调用 logging.config.fileConfig():import loggingfrom logging.config import fileConfigfileConfig(logging_config.ini)logge

152、r = logging.getLogger()logger.debug(often makes a very good meal of %s, visiting tourists)使使使用用用字字字典典典配配配置置置的的的例例例子子子在Python 2.7中,可以使用包含有详细配置的字典。PEP 391 中列出了在配置字典中哪些元素是必备的,以及哪些元素是可选的。import loggingfrom logging.config import dictConfiglogging_config = dict(version = 1,formatters = f: format:%(asctime

153、)s %(name)-12s %(levelname)-8s %(message)s,handlers = h: class: logging.StreamHandler,formatter: f,level: logging.DEBUG,root = handlers: h,level: logging.DEBUG,)dictConfig(logging_config)logger = logging.getLogger()logger.debug(often makes a very good meal of %s, visiting tourists)直直直接接接在在在代代代码码码中中中

154、配配配置置置的的的例例例子子子import logginglogger = logging.getLogger()handler = logging.StreamHandler()formatter = logging.Formatter(%(asctime)s %(name)-12s %(levelname)-8s %(message)s)handler.setFormatter(formatter)logger.addHandler(handler)logger.setLevel(logging.DEBUG)40Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python

155、Guide Documentation, 发发发布布布 0.0.1logger.debug(often makes a very good meal of %s, visiting tourists)常常常见见见的的的问问问题题题很大程度上来讲,Python作为一门简洁一致的语言,会尽量避免一些让人感到惊讶的特性。然而,还是有一些情况会让新手感到迷惑不解。这些情形中的一些是故意为之,但却可能会令人感到惊讶。一些则已被证明是语言的缺陷。通常,对于一系列难以捉摸的行为,乍一看很奇怪,但是一旦你明白这种惊讶背后的底层原因,你就会觉得合乎情理。可可可变变变的的的默默默认认认参参参数数数对于Python

156、初学者而言,最为常见、看起来令人惊讶的就是Python对于函数定义中可变默认参数的处理。你你你所所所写写写的的的代代代码码码def append_to(element, to=):to.append(element)return to你你你所所所期期期望望望发发发生生生的的的my_list = append_to(12)print my_listmy_other_list = append_to(42)print my_other_list每次调用函数时,如果第二个参数没有提供,那么应该创建一个新的列表,所以输出应该是:1242事事事实实实上上上发发发生生生的的的1212, 42一旦函数被定义

157、后,新的列表就会被创建,后续的每次函数调用都会使用同一个列表。当函数被定义时,Python的默认参数就会被求值,而不是发生在每次函数调用时(这和Ruby是一样的)。这就意味着,如果你使用了可变的默认参数且改变该参数,你 将会 并且已经无意识的修改了之后所有调用该函数时的参数对象。如如如何何何处处处理理理这这这种种种情情情况况况每次函数调用时,通过使用一个默认的参数值(None 通常是一个好的选择)来提示该调用未提供参数,这时再创建一个新的对象。2.7. 常常常见见见的的的问问问题题题41Python Guide Documentation, 发发发布布布 0.0.1def append_to(

158、element, to=None):if to is None:to = to.append(element)return to当当当问问问题题题就就就不不不再再再是是是问问问题题题有时候你可以专门“利用”(注:按所预期的使用)这个行为来维护函数调用之间的状态。通常在编写缓存函数的时候会用到这个特性。延延延迟迟迟绑绑绑定定定闭闭闭包包包另外一个迷惑源自Python在闭包中绑定变量的方式(或在周围全局作用域)。你你你所所所写写写的的的代代代码码码def create_multipliers():return lambda x : i*x for i in range(5)你你你所所所期期期望望望

159、发发发生生生的的的for multiplier in create_multipliers():print multiplier(2)包含有5个函数的列表,每个函数拥有自己的封闭的 i 变量来与其参数进行乘运算,产生结果如下:02468事事事实实实上上上发发发生生生的的的888885个函数都已创建,然而这些函数却都把 x 乘以4。Python的闭包采用 延迟绑定 。这意味着,闭包中使用到的变量,它的值是在内部函数被调用时才会进行查找。这里例子中,无论何时,当所返回函数中的 任何 一个进行调用时, i 的值只有在调用时刻才在周边作用域中进行查找。而此刻,循环操作早已结束且 i 最后的值已变为4。

160、对于这个问题,更糟糕的一点是对这个结果的广泛误解:人们以为这与Python中的 lambdas 有关。其实,使用 lambda 表达式创建的函数没有任何特殊,事实上,使用常用的 def 创建的函数同样存在这个问题。42Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码Python Guide Documentation, 发发发布布布 0.0.1def create_multipliers():multipliers = for i in range(5):def multiplier(x):return i*xmultipliers.append(multiplier)retu

161、rn multipliers如如如何何何处处处理理理这这这种种种情情情况况况最为常用的解决方案可能需要一点hack。多亏前面提及的关于函数参数默认值求值问题(参见 可变的默认参数 ),你可以创建一个闭包,然后利用默认的参数值立刻绑定其参数,就像下面这样:def create_multipliers():return lambda x, i=i : i*x for i in range(5)另外一个方案,你可以使用函数 functools.partial:from functools import partialfrom operator import muldef create_multipl

162、iers():return partial(mul, i) for i in range(5)当当当问问问题题题就就就不不不再再再是是是问问问题题题有时候,你是希望闭包可以按照这种延迟绑定的行为来执行的。在很多情形下,延迟绑定是非常有用的。当然,很不幸,通过循环来创建唯一函数成了一个反例的情形。无无无处处处不不不在在在的的的字字字节节节码码码(.pyc)文文文件件件默认情况下,当从一个文件执行Python代码的时候,Python解释器会自动在磁盘上产生该文件的字节码文件,例如: module.pyc 。这些 .pyc 文件不应该提交到源码的版本库中。从理论上讲,由于性能的原因,这种行为默认是开

163、启的。因为如果没有这些字节码文件,每次源码文件被载入执行时,都需要重新生成字节码。禁禁禁用用用字字字节节节码码码(.pyc)文文文件件件幸运的是,产生字节码的过程极其快速,所以在开发代码的时候并不需要担心这些。当然,这些字节码文件相当的烦人,所以可以通过下面的方法来摆脱它们:$ export PYTHONDONTWRITEBYTECODE=1一旦设置 $PYTHONDONTWRITEBYTECODE 环境变量,Python就不会再产生字节码文件,这样你的开发环境可以保持干净整洁。我建议在你的 /.profile 文件中设置这个环境变量。2.7. 常常常见见见的的的问问问题题题43Python

164、Guide Documentation, 发发发布布布 0.0.1移移移除除除字字字节节节码码码(.pyc)文文文件件件如果已经存在字节码文件,下述命令可以移除这些文件:$ find . -type f -name *.pyco -delete -or -type d -name _pycache_ -delete在项目的跟目录下执行这行命令,所有的 .pyc 文件瞬间就会消失的无影无踪。6不6?选选选择择择许许许可可可证证证源码发布 需要 一个许可证。在灯塔国,如果没有指明许可证,用户是没有合法权利进行下载、修改或者再分发的。进一步讲,人们也无法向你的代码进行贡献,除非你告诉他们应该遵守什么

165、规则。挑选合适的许可证比较复杂,这里给出一些指点:开源。有大量的 开源许可证 可供选择。通常,这些许可证属于以下这两类中的一种:1. 许可证更多地聚焦于用户按照其意愿使用软件的自由(这类许可证更加宽容,例如MIT、BSD以及Apache)。2. 另一类许可证更多地聚焦于确保代码本身 包括对代码任何的修改和分发 总是保持自由开放(这类不那么宽容的许可证包括GPL以及LGPL)。后一种许可证不允许用户在软件上添加代码却在分发时不包含这部分更改的源码(译者注:即作出的更改必须也开源),就这点而言,显得不太宽容。为了帮助你给自己的项目选择一个合适的许可证,这里有一份 如何选择许可证 ,参参参考考考下下

166、下吧吧吧 。更更更加加加宽宽宽容容容的的的许许许可可可证证证 PSFL (Python Software Foundation License) 用于Python本身 MIT / BSD / ISC MIT (X11) New BSD ISC Apache不不不那那那么么么宽宽宽容容容的的的许许许可可可证证证 LGPL GPL GPLv2 GPLv3tl;drLegal 是一份许可证概览,里面解释了用户在使用一个特定软件时能做什么、不能做什么以及必须做什么。44Chapter 2. 写写写出出出优优优雅雅雅的的的代代代码码码CHAPTER3Python应应应用用用场场场景景景本章主要聚焦于不同

167、场景下工具和模块的使用建议。网网网络络络应应应用用用HTTP超文本传输协议是一种用于分布式、协作化、超媒体信息系统的应用协议。HTTP是万维网中数据交互的基础。RequestsPython标准库中的urllib2模块提供了你可能会用到的绝大部分HTTP功能,然而,该模块的API却十分难用。该模块是为不同时间段、不同web构建的。所以,即使要完成一个很简单的任务也需要大量的工作(甚至需要重写一些方法)。Requests做了Python HTTP的所有工作 可以无缝的集成web服务。通过使用Requests,不再需要人工添加查询字符串到URL中,又或者编码POST数据。Keep-alive以及HT

168、TP连接池都是100%的自动完成,这是通过内嵌在Requests中的urllib3来完成的, 参考文档 PyPi GitHub分分分布布布式式式系系系统统统ZeroMQMQ(也写作ZeroMQ、0MQ或ZMQ)是一个高性能的异步消息库,旨在用于高扩展性的分布式或并发应用中。它提供了一个消息队列,但与面向消息的中间件有所不同, MQ系统不需要特定的消息协商器就可以运行。库本身的设计与socket API有着相似的接口。45Python Guide Documentation, 发发发布布布 0.0.1RabbitMQRabbitMQ是一个实现了高级消息队列协议(AMQP)的开源消息协商器软件。R

169、abbitMQ服务器采用Erlang编程语言实现,并且构建在开放电信平台(OTP)上来达到集群化和容错。所有主流的编程语言都实现了与协商器交互的客户端。 主页 GitHub组织Web应应应用用用及及及框框框架架架作为一种适用于快速原型以及大型项目的强大脚本语言,Python在Web应用开发中被广泛使用。上上上下下下文文文环环环境境境WSGIWeb服务器网关接口(缩写为“WSGI”)是Python web应用框架与web服务器交互的标准接口。通过标准化Python web框架与web服务器之间的行为和交互,WSGI使得编写可部署于任何 WSGI兼容服务器 上的可移植性Python代码变成了可能。

170、WSGI的相关文档见 PEP 3333 。框框框架架架大体上来说,web框架包含了各种库的集合,以及用于定制代码实现web应用(比如一个交互式的web站点)的主处理器。大部分的web框架包含了各种模式以及工具来实现以下几点:URL路路路由由由 匹配到来的HTTP请求到特定的Python代码来执行相应逻辑请请请求求求响响响应应应对对对象象象 对接收自或发送给用户浏览器的信息进行包装模模模板板板引引引擎擎擎 用于分离实现应用逻辑的Python代码和产生的HTML(或其他形式)输出开开开发发发时时时使使使用用用的的的web服服服务务务器器器 在开发机上运行HTTP服务器可以进行快速开发;当文件更新时

171、,通常会自动重载服务端代码。DjangoDjango 是一个“内置电池”的web应用框架,对于创建面向内容的站点来说是一个极好的选择。通过提供大量开箱即用的工具和模式,Django旨在鼓励以最佳实践方式编写代码的同时,可以快速构建复杂的、数据库驱动的web应用。Django有着一个活跃的大型社区,有许多预先构建好的 可复用模块 可以用来构建新的项目,抑或通过定制来达到你的要求。在 美国 和 欧洲 每年都有Django的会议。当今大多数新的Python web应用都是使用Django来构建的。46Chapter 3. Python应应应用用用场场场景景景Python Guide Document

172、ation, 发发发布布布 0.0.1FlaskFlask 是Python中的一个 “微框架”,对于构建小型的应用、API或者web服务,这是一个极好的选择。使用Flask构建应用在很大程度上就和编写标准Python模块差不多,除了要绑定路由到一些函数之上。这种方式棒极了。Flask并没有向你提供可能会用到的所有功能,而是实现了web应用框架中大部分常用的核心组件,比如URL路由、请求响应对象和模板。如果采用Flask,你可以根据自己爱好来为你的应用选择其他任何组件。比如,Flask并没有内建数据库访问或者表单的生成与验证。这样做其实很好,因为很多web应用并不需要这些特性。对于那些需要这些特

173、性的项目而言,有许多 扩展可以满足你的需求。又或者你可以使用任何你想用的库!对于那些不太适用Django的Python web应用来说,Flask是默认的选择。TornadoTornado 是Python中的一个异步web框架,有着自己的事件循环,这使得其本身可以支持WebSockets。优秀的tornado应用以性能卓越而著称。我不太建议使用Tornado,除非你认为非用不可。PyramidPyramid 是一个聚焦于模块化、极具伸缩性的框架。框架本身内建有少量的库(“电池”),并鼓励用户扩展这些基础功能。不像Django和Flask,Pyramid用户基础并不大。本身是一个功能很强大的框架

174、,但是对于如今新的Pythonweb应用来说并不是一个流行的选择。Web服服服务务务器器器NginxNginx (发音 “engine-x”)是一个web服务器以及HTTP、SMTP和其他协议的反向代理。以高性能、相对简单及和许多应用服务器的(如WSGI服务器)兼容性著称。它包含有大把的特性,比如负载均衡、基本认证、流处理以及其他特性。Nginx设计用以服务于高负载的站点,正在逐渐变得越来越流行。WSGI服服服务务务器器器独立的WSGI服务器往往比传统的web服务器使用更少的资源,并且提供更高的性能3。GunicornGunicorn (Green Unicorn)是一个用来驱动Python应

175、用的WSGI服务器,纯Python实现。与其他Python web服务器不同,它有着非常体贴的接口,并且非常易用和配置。Gunicorn有着很明智合理的默认配置。然而,一些其他服务器,例如uWSGI,虽然有着惊人的可定制性,但也因此变得更加难以高效使用。3Python WSGI服务器基准测试3.2. Web应应应用用用及及及框框框架架架47Python Guide Documentation, 发发发布布布 0.0.1对于如今新的Python web应用而言,Gunicorn是更加推荐的选择。WaitressWaitress 也是一个纯Python的WSGI服务器,声称有着“非常可接受的性能”

176、。其文档并不太详细,但是确实提供了一些Gunicorn没有提供的优秀功能(如HTTP请求缓冲)。Waitress在Python web开发社区正在变得越来越流行。uWSGIuWSGI 为构建托管服务提供了全栈的功能。除了进程管理、进程监控以及其他功能,uWSGI还可以作为多种编程语言和协议的应用服务器 - 当然包括Python和WSGI。uWSGI既可以作为独立的web路由器来运行,也可以运行在全功能的web服务器(比如Nginx和Apache)后端。后一种情况下,web服务器可以配置uWSGI与应用之间采用 uwsgi协议 来通信。uWSGI的web服务器支持通过传递环境变量和进一步的调整来

177、动态配置Python。更详细的信息,参见 uWSGI魔法变量 。我不建议使用uWSGI,除非你知道为什么需要使用。服服服务务务端端端最最最佳佳佳实实实践践践当前主流部署Python应用的方式主要是采用如 Gunicorn 的WSGI服务器,然后直接或间接的放置在轻量级web服务器,如 nginx 后面。WSGI服务器主要是用于Python应用的处理,与此同时,web服务器则处理更适合它的任务,比如静态文件服务、请求路由、DDoS保护以及基本认证。托托托管管管部部部署署署平台即服务(PaaS)是一种云计算基础设施的类型,会抽象并管理基础设施、路由以及web应用的扩展。使用PaaS时,应用开发者可

178、以聚焦于编写应用代码而不用关心部署的细节。HerokuHeroku 对Python 2.7-3.5 应用提供了第一流的支持。Heroku支持所有类型的Python web应用、服务器以及框架。可以在Heroku上免费的开发应用。一旦应用可以用于生产,你可以升级到兴趣或专业应用。Heroku维护了 详细的文章 来说明如何在Heroku上使用Python,同时也有一份 手把手指南 来帮助设置你的第一个应用。Heroku是当前比较推荐的用于部署Python web应用的PaaS。EldarionEldarion (之前叫做Gondor)由Kubernetes、CoreOS和Docker构建的PaaS

179、平台。该平台支持任何WSGI应用,并且有一份指南说明如何部署 Django项目 。48Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1模模模板板板大多数WSGI应用会以HTML或其他标记语言作为HTTP请求的响应。关注点分离的概念建议我们采用模板,而不是直接从Python中产生文本内容。模板引擎管理着一系列的模板文件,采用层次系统和包含系统来避免不必要的重复,并负责渲染(生成)实际的内容,利用应用产生的动态内容来填充模板的静态内容。由于模板文件有时会由设计人员或者前端开发者来编写,因此处理起不断增长的复杂

180、性会很困难。对于如何把应用中的动态内容传递给模板引擎和模板本身,有一些通用且好的实践可供参考: 应当只把渲染时必要的动态内容传递给模板文件。避免传递额外的内容“以防万一”:添加缺失的变量远比移除一个不用的变量要容易。 许多模板引擎允许在模板中使用复杂的语句或赋值,并且还允许在模板中调用Python代码。这种便捷会导致复杂性的不可控,进而使得很难找到bug。 通常情况下需要把Javascript模板与HTML模板混合。对于这种设计来说,一个明智的方式是把需要由HTML模板传递变量内容到JavaScript代码的部分隔离。Jinja2Jinja2 是一个得到普遍好评的模板引擎。它采用基于文本的模板

181、语言,这样就可以用于生成任何类型的标记语言,不仅仅是HTML。Jinja2允许定制过滤器、标签、测试以及全局内容。相比于Django的模板系统,Jinja2有许多的改进。这里是Jinja2中一些重要的HTML标签:# 这是注释 # 下一个标签是变量输出 #title# 块标签,通过继承可以被其他html代码替换 #% block head %This is the head!% endblock %# 迭代输出数组 #% for item in list % item % endfor %接下来的代码清单是一个与Tornado服务器结合的web站点示例。Tornado使用起来并不复杂。# 导入

182、Jinja2from jinja2 import Environment, FileSystemLoader# 导入Tornadoimport tornado.ioloopimport tornado.web# 载入模板文件 templates/site.htmlTEMPLATE_FILE = site.htmltemplateLoader = FileSystemLoader( searchpath=templates/ )templateEnv = Environment( loader=templateLoader )template = templateEnv.get_template

183、(TEMPLATE_FILE)# 用于渲染的著名电影列表3.2. Web应应应用用用及及及框框框架架架49Python Guide Documentation, 发发发布布布 0.0.1movie_list = 1,The Hitchhikers Guide to the Galaxy,2,Back to future,3,Matrix# template.render() 返回包含有渲染后html的字符串html_output = template.render(list=movie_list,title=Here is my favorite movie list)# 主页的处理器clas

184、s MainHandler(tornado.web.RequestHandler):def get(self):# 返回渲染后的模板字符串到浏览器self.write(html_output)# 设定路由(127.0.0.1:PORT/)application = tornado.web.Application(r/, MainHandler),)PORT=8884if _name_ = _main_:# 设置服务器application.listen(PORT)tornado.ioloop.IOLoop.instance().start()base.html 文件可以作为所有站点页面的基础,

185、这些站点页面实现其中的内容块即可。title - My Webpage# 下一行会由site.html模板中的内容填充 #% block content % endblock % block footer %© Copyright 2013 by you.% endblock %下一代码清单是我们Python应用载入的的站点页面( site.html ),该页面扩展了 base.html 。内容块会自动嵌入到 base.html 页面对应的块中。!% extends base.html % block content %title list_title % for item in l

186、ist % item0 : item1% endfor %50Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1% endblock %对于新的Python web应用,Jinja2是比较推荐的模板库。ChameleonChameleon 页面模板是一个HTML/XML模板引擎,该引擎实现了 模板属性语言 (TAL) 、 TAL表达式语法(TALES) 和 宏扩展TAL (Metal) 语法。Chameleon可用于Python 2.5及以上版本(包括3.x和pypy),常用于 Pyramid框架 。页面模

187、板会在你的文档结构中添加特殊的元素属性和文本标记。通过使用一组简单的语言构造,你可以控制文档流、元素的重复、文本的替换和转化。由于是基于属性的语法,未渲染的页面模板是合法的HTML,所以可以在浏览器中查看,也可以在WYSIWYG的编辑器中编辑。这使得与设计师来回的协作,以及在浏览器中使用静态文件构建原型变得更加容易。基本的TAL语言可以很容易的从下面的例子中了解:Hello, World! 是插入文本的模式,它是如此常见,以至于当你不需要保证未渲染的模板严格合法时,你可以使用更加简短可读的语法来替换,即 $expression ,具体如下:Hello, $world!$row.capitali

188、ze() $col但是请记住完整的 Default Text 语法还允许在未渲染的模板中包含默认内容。由于Chameleon来自Pyramid世界,所以并未广泛使用。MakoMako 是一种会编译为Python的模板语言,以达到性能最大化。它的语法和API借鉴于其他模板语言(比如Django和Jinja2)最好的部分,它是 Pylons and Pyramid web框架包含的默认模板语言。Mako模板示例如下:3.2. Web应应应用用用及及及框框框架架架51Python Guide Documentation, 发发发布布布 0.0.1% for row in rows:$makerow(

189、row)% endfor% for name in row:$name% endfor要想渲染一个最基本的模板,你可以这样做:from mako.template import Templateprint(Template(hello $data!).render(data=world)在Python web社区,Mako备受推崇。参参参考考考HTML页页页面面面爬爬爬取取取网网网页页页爬爬爬取取取网站采用HTML编写,这意味着每个网页都是一个结构化的文档。有时候我们往往需要从这些网页中获取一些数据,与此同时还要保留其结构。网站一般不会以合适的格式来提供他们的数据,比如采用 csv 或者jso

190、n 。这时,网页爬取就派上了用场。网页爬取是一种采用电脑程序在网页上筛选并收集数据的行为,这些数据以对你最为有用的格式来保存,同时还保留了其结构。lxml与与与Requestslxml 是一个用来快速解析XML和HTML文档且具有良好扩展性的库,甚至可以处理各种杂乱的标签。我们还会使用 Requests 模块来替代内置的urllib2模块,以便提高速度和可读性。你可以很容易的使用命令 pipinstall lxml 和 pip install requests 来安装。首先,导入这两个库:from lxml import htmlimport requests接下来我们将使用 requests

191、.get 来获取包含我们所需数据的网页,采用 html 模块来解析,并把结果保存在 tree 中。page = requests.get(http:/ = html.fromstring(page.content)52Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1我们应该使用 page.content 而不是 page.text ,因为 html.fromstring 默认使用 bytes 来作为输入。tree 现在以良好的树状结构包含整个HTML文件,我们可以采用两种方式来遍历:XPath和CSSSe

192、lect。在这个示例中,我们主要介绍前一种。XPath是一种在HTML或XML等结构化文档中定位信息的方式。 W3Schools 上有对XPath很好的介绍。此外还有各种各样的工具来获取元素的XPath,比如Firefox中的FireBug或者Chrome中的Inspector。如果你正在使用Chrome,你可以右击元素,选择“检查”,高亮对应的代码,再次右击然后选择 “Copy - CopyXPath”。快速分析下面代码后,可以发现在我们的页面中,数据包含在两个元素之中 - 一个是title为”buyer-name”的div块,另外一个是class为”item-price”的span。Car

193、son Busses$29.95知道这些后,我们可以构造一个正确的XPath查询,并且按下列方式使用lxml中的 xpath 函数:# 此处会构造一个购买者的列表:buyers = tree.xpath(/divtitle=buyer-name/text()# 此处会构造一个价格的列表:prices = tree.xpath(/spanclass=item-price/text()我们来看看得到的确切数据是什么:print Buyers: , buyersprint Prices: , pricesBuyers:Carson Busses, Earl E. Byrd, Patty Cakes,

194、Derri Anne Connecticut, Moe Dess, Leda Doggslife, Dan Druff,Al Fresco, Ido Hoe, Howie Kisses, Len Lease, Phil Meup,Ira Pent, Ben D. Rules, Ave Sectomy, Gary Shattire,Bobbi Soks, Sheila Takya, Rose Tattoo, Moe TellPrices:$29.95, $8.37, $15.26, $19.25, $19.25,$13.99, $31.57, $8.49, $14.47, $15.86, $11

195、.11,$15.98, $16.27, $7.50, $50.85, $14.26, $5.68,$15.00, $114.07, $10.09恭喜恭喜!我们已经成功的使用lxml和Requests从网页中爬取到了所有我们想要的数据。目前这些数据以两个列表的形式保存在内存中。这时候就可以在这些数据上做各种很酷的操作了:我们可以使用Python来分析这些数据或者把这些数据保存在一个文件中,然后分享给其他人。可以想一些更加酷的idea,比如修改这个脚本来迭代处理网页剩下的部分,或者使用线程重写该应用来提高速度。命命命令令令行行行应应应用用用命令行应用也叫 控制台应用 ,是为文本界面设计的电脑程序,

196、 比如 shell 。命令行应用通常接收多个输入作为参数或者子命令, 同时还会接收一些选项来作为标识或开关。一些流行的命令行应用包括: Grep - 文本数据搜索工具 curl - 采用URL语法进行数据传输的工具 httpie - HTTP客户端命令行工具,是cURL更为友好的替代品3.4. 命命命令令令行行行应应应用用用53Python Guide Documentation, 发发发布布布 0.0.1 git - 一种分布式版本控制系统 mercurial - 一种分布式版本控制系统,主要采用Python开发Clintclint 是一个用于开发命令行应用的Python模块,包含很多有用的

197、工具, 支持的特性包括:命令行颜色/缩排、简单强大的列输出、基于迭代器的进度条以及隐式参数处理等。Clickclick (Command-line Interface Creation Kit,首字母缩写) 是一个使用尽可能少的代码来实现命令行接口的Python包,该包采用了组合方式来实现。这个“命令行接口构造工具”具有开箱即用的默认设置,同时不失高可配置性。docoptdocopt 是一个轻量且Pythonic的包。通过解析POSIX风格的指令来创建命令行接口,很直观易用。PlacPlac 是对Python标准库中的 argparse 的简单包装, 采用声明式接口(即通过推断而不是手写命令的

198、方式来构建出参数解析器)来隐藏其复杂性。其目标用户包括:初级用户、 程序员、系统管理员、科学家以及那些编写用完即扔脚本的人,该工具可以帮助他们快速简单的创建命令行接口。CliffCliff 是一个构建命令行程序的框架。它采用了setuptools的入口点 来提供子命令、格式化输出以及其他扩展。该框架目的是用于创建包含多层级的命令,比如subversion和git,这些程序会处理某个 基本参数的解析,然后再调用对应的子命令来进行具体的工作。CementCement 是一个先进的命令行应用框架,其目标是在不牺牲高品质的前提下,引入一个标准化、特性齐全的平台, 该平台对于各种复杂程度的命令行应用提供

199、良好支持,同时还能满足快速开发。Cement具有高伸缩性,使用场景就可以满足微框架的简单性,也可以 满足大型框架的复杂性。GUI应应应用用用按字母排序的GUI应用列表。54Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1CamelotCamelot 受Django管理界面的启发,在Python、SQLAlchemy和Qt的基础上提供了各种组件来构建应用。可 用 的 参 考 资 源 主 要 是 其 网 站 :http:/www.python-和 邮 件 列 表:https:/ Cocoa框架仅用于OS X,

200、如果要编写跨平台的应用就不要考虑了。GTKPyGTK提供了对GTK+工具集的Python绑定。与GTK+库本身一样,也采用了GNU LGPL许可证。需要注意的是PyGTK目前只支持GTK-2.X的API(不支持GTK-3.0)。 对于新项目来说目前已不推荐使用PyGTK,现有的PyGTK应用也推荐迁移到PyGObject上。PyGObject 又又又叫叫叫(PyGi)PyGObject 提供了整个GNOME软件平台的Python绑定,且与GTK+ 3完全兼容。 这里有一份入门资料 PythonGTK+ 3指南 。API参考KivyKivy 是一个Python库,可用于开发多点触屏的富媒体应用。

201、其目标是为了能够进行快速轻松的交互设计及快速原型, 同时保证代码的可重用性和可部署性。Kivy采用Python编写,基于OpenGL,支持多种输入设备,例如:鼠标、双向鼠标、TUIO触摸协议、Wii控制器、 Windows的WM_TOUCH消息、HID触摸以及苹果公司的产品等等。Kivy由一个社区进行开发,非常活跃且免费使用,可在所有主流平台(Linux, OSX, Windows, Android)上使用。主要资源可以在其网站上找到:http:/kivy.orgPyObjC注注注解解解: Cocoa框架仅用于OS X,如果要编写跨平台的应用就不要考虑了。PySidePySide是对跨平台GU

202、I工具Qt的Python绑定。pip install pysidehttps:/wiki.qt.io/Category:LanguageBindings:PySide:Downloads3.5. GUI应应应用用用55Python Guide Documentation, 发发发布布布 0.0.1PyQt注注注解解解: 如果你的软件没有完全遵从GPL,那么你需要购买商业许可证!PyQt提供了Qt框架的Python绑定(见后面)。http:/www.riverbankcomputing.co.uk/software/pyqt/downloadPyjamasDesktop (pyjs Deskto

203、p)PyjamasDesktop是Pyjamas的移植。PyjamasDesktop是一组用于桌面及跨平台框架的组件集,v0.6版本之后,PyjamasDesktop成了Pyjamas(Pyjs)的一部分。 简单来说,就是可以采用与Python Web应用完全相同的代码但是作为独立桌面应用来执行。PyjamasDesktop的Python Wiki 。主页: pyjs Desktop 。QtQt 是一个广泛使用的跨平台应用框架,可用于开发GUI以及非GUI应用。TkTkinter是Tcl/Tk之上很薄的面向对象包装层。 可可可以以以使使使用用用Python标标标准准准库库库的的的优优优势势势使

204、使使得得得它它它成成成为为为最最最方方方便便便且且且兼兼兼容容容性性性良良良好好好编编编程程程工工工具具具集集集 。Tk和Tkinter二者都可以在大多数的Unix平台使用,当然Windows及Macintosh系统也同样支持。从8.0版本开始,Tk在所有平台提供了原生界面的支持。TkDocs 上有一份非常不错的多语言Tk教程,包含了Python的示例。更多信息见 Python Wiki 。wxPythonwxPython是一个Python语言的GUI工具集。可以让Python程序员很简便的创建出健壮、功能丰富的图形用户界面。 它是一个Python的扩展模块(原生代码),通过包装著名的跨平台C

205、+ GUI库wxWidgets来实现。安安安装装装wxPython: 到 http:/www.wxpython.org/download.php#stable 下载适合你所使用操作系统的包。数数数据据据库库库DB-APIThe Python Database API (DB-API) defines a standard interface for Python database access modules. Its documentedin PEP 249. Nearly all Python database modules such as sqlite3, psycopg and my

206、sql-python conform to this interface.Tutorials that explain how to work with modules that conform to this interface can be found here and here.56Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1SQLAlchemySQLAlchemy is a commonly used database toolkit. Unlike many database librari

207、es it not only provides an ORM layerbut also a generalized API for writing database-agnostic code without SQL.$ pip install sqlalchemyRecordsRecords is minimalist SQL library, designed for sending raw SQL queries to various databases. Data can be usedprogrammatically, or exported to a number of usef

208、ul data formats.$ pip install recordsAlso included is a command-line tool for exporting SQL data.Django ORMThe Django ORM is the interface used by Django to provide database access.Its based on the idea of models, an abstraction that makes it easier to manipulate data in Python.The basics: Each mode

209、l is a Python class that subclasses django.db.models.Model. Each attribute of the model represents a database field. Django gives you an automatically-generated database-access API; see Making queries.peeweepeewee is another ORM with a focus on being lightweight with support for Python 2.6+ and 3.2+

210、 which supportsSQLite, MySQL and Postgres by default. The model layer is similar to that of the Django ORM and it has SQL-likemethods to query data. While SQLite, MySQL and Postgres are supported out-of-the-box, there is a collection ofadd-ons available.PonyORMPonyORMisanORMthattakesadifferentapproa

211、chtoqueryingthedatabase. InsteadofwritinganSQL-likelanguageor boolean expressions, Pythons generator syntax is used. Theres also an graphical schema editor that can generatePonyORM entities for you. It supports Python 2.6+ and Python 3.3+ and can connect to SQLite, MySQL, Postgres &OracleSQLObjectSQ

212、LObject is yet another ORM. It supports a wide variety of databases: Common database systems MySQL, Postgresand SQLite and more exotic systems like SAP DB, SyBase and MSSQL. It only supports Python 2 from Python 2.6upwards.3.6. 数数数据据据库库库57Python Guide Documentation, 发发发布布布 0.0.1网网网络络络TwistedTwisted

213、是一个事件驱动的网络引擎。可以用来构建基于多种不同网络协议的应用程序,包括http服务器/客户端、使用SMTP/POP3/IMAP或SSH协议的应用、即时通信应用以及 更多 。PyZMQPyZMQ 是 ZeroMQ 的Python绑定。ZeroMQ是一个高性能的异步消息库,其中一个最大的优点是采用了无代理的方式来处理消息队列。ZeroMQ的基本模式如下: 请求-应答: 把一组客户端关联到一组服务上。这属于一种远程过程调用及任务分发模式。 发布-订阅: 把一组发布者关联到一组订阅者上。这是一种数据分发模式。 推送-拉取(或管道): 采用多阶段及循环输出/输入模式把一组节点关联起来。这是一种并行任

214、务分发及收集模式。快速上手参见 ZeroMQ指南 。geventgevent 是一个基于协程的Python网络库,在libev事件循环上利用greenlets封装了更加高层的同步API。Systems AdministrationFabricFabric is a library for simplifying system administration tasks. While Chef and Puppet tend to focus on managingservers and system libraries, Fabric is more focused on application

215、 level tasks such as deployment.Install Fabric:$ pip install fabricThe following code will create two tasks that we can use: memory_usage and deploy. The former will output thememory usage on each machine. The latter will ssh into each server, cd to our project directory, activate the virtualenviron

216、ment, pull the newest codebase, and restart the application server.from fabric.api import cd, env, prefix, run, taskenv.hosts = my_server1, my_server2taskdef memory_usage():run(free -m)taskdef deploy():with cd(/var/www/project-env/project):with prefix(. ./bin/activate):58Chapter 3. Python应应应用用用场场场景景

217、景Python Guide Documentation, 发发发布布布 0.0.1run(git pull)run(touch app.wsgi)With the previous code saved in a file named fabfile.py, we can check memory usage with:$ fab memory_usagemy_server1 Executing task memorymy_server1 run: free -mmy_server1 out:totalusedfreesharedbufferscachedmy_server1 out: Mem

218、:6964189750670166222my_server1 out: -/+ buffers/cache:15095455my_server1 out: Swap:000my_server2 Executing task memorymy_server2 run: free -mmy_server2 out:totalusedfreesharedbufferscachedmy_server2 out: Mem:16669027640180572my_server2 out: -/+ buffers/cache:1481517my_server2 out: Swap:8951894and we

219、 can deploy with:$ fab deployAdditional features include parallel execution, interaction with remote programs, and host grouping.Fabric DocumentationSaltSalt is an open source infrastructure management tool. It supports remote command execution from a central point(master host) to multiple hosts (mi

220、nions). It also supports system states which can be used to configure multiple serversusing simple template files.Salt supports Python versions 2.6 and 2.7 and can be installed via pip:$ pip install saltAfter configuring a master server and any number of minion hosts, we can run arbitrary shell comm

221、ands or use pre-built modules of complex commands on our minions.The following command lists all available minion hosts, using the ping module.$ salt * test.pingThe host filtering is accomplished by matching the minion id, or using the grains system. The grains system uses statichost information lik

222、e the operating system version or the CPU architecture to provide a host taxonomy for the Saltmodules.The following command lists all available minions running CentOS using the grains system:$ salt -G os:CentOS test.pingSalt also provides a state system. States can be used to configure the minion ho

223、sts.For example, when a minion host is ordered to read the following state file, it will install and start the Apache server:apache:pkg:- installed3.8. Systems Administration59Python Guide Documentation, 发发发布布布 0.0.1service:- running- enable: True- require:- pkg: apacheState files can be written usi

224、ng YAML, the Jinja2 template system or pure Python.Salt DocumentationPsutilPsutil is an interface to different system information (e.g. CPU, memory, disks, network, users and processes).Here is an example to be aware of some server overload. If any of the tests (net, CPU) fail, it will send an email

225、.# Functions to get system values:from psutil import cpu_percent, net_io_counters# Functions to take a break:from time import sleep# Package for email services:import smtplibimport stringMAX_NET_USAGE = 400000MAX_ATTACKS = 4attack = 0counter = 0while attack 70:attack = attack + 1# Check the net usag

226、eneti1 = net_io_counters()1neto1 = net_io_counters()0sleep(1)neti2 = net_io_counters()1neto2 = net_io_counters()0# Calculate the bytes per secondnet = (neti2+neto2) - (neti1+neto1)/2if net MAX_NET_USAGE:attack = attack + 1if counter 25:attack = 0counter = 0# Write a very important email if attack is

227、 higher than 4TO = youyour_FROM = webmasteryour_SUBJECT = Your domain is out of system resources!text = Go and fix your server!BODY = string.join(From: %s %FROM,To: %s %TO,Subject: %s %SUBJECT, ,text), rn)server = smtplib.SMTP(127.0.0.1)server.sendmail(FROM, TO, BODY)server.quit()A full terminal app

228、lication like a widely extended top which is based on psutil and with the ability of a client-servermonitoring is glance.60Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1AnsibleAnsible is an open source system automation tool. The biggest advantage over Puppet or Chef is it doe

229、s not require anagent on the client machine. Playbooks are Ansibles configuration, deployment, and orchestration language and arewritten in YAML with Jinja2 for templating.Ansible supports Python versions 2.6 and 2.7 and can be installed via pip:$ pip install ansibleAnsible requires an inventory fil

230、e that describes the hosts to which it has access. Below is an example of a host andplaybook that will ping all the hosts in the inventory file.Here is an example inventory file: hosts.ymlserver_name127.0.0.1Here is an example playbook: ping.yml- hosts: alltasks:- name: pingaction: pingTo run the pl

231、aybook:$ ansible-playbook ping.yml -i hosts.yml -ask-passThe Ansible playbook will ping all of the servers in the hosts.yml file. You can also select groups of servers usingAnsible. For more information about Ansible, read the Ansible Docs.An Ansible tutorial is also a great and detailed introductio

232、n to getting started with Ansible.ChefChef is a systems and cloud infrastructure automation framework that makes it easy to deploy servers and applicationsto any physical, virtual, or cloud location. In case this is your choice for configuration management, you will primarilyuse Ruby to write your i

233、nfrastructure code.Chef clients run on every server that is part of your infrastructure and these regularly check with your Chef server toensure your system is always aligned and represents the desired state. Since each individual server has its own distinctChef client, each server configures itself

234、 and this distributed approach makes Chef a scalable automation platform.Chef works by using custom recipes (configuration elements), implemented in cookbooks. Cookbooks, which arebasically packages for infrastructure choices, are usually stored in your Chef server. Read the Digital Ocean tutorialse

235、ries on chef to learn how to create a simple Chef Server.To create a simple cookbook the knife command is used:knife cookbook create cookbook_nameGetting started with Chef is a good starting point for Chef Beginners and many community maintained cookbooks thatcan serve as a good reference or tweaked

236、 to serve your infrastructure configuration needs can be found on the ChefSupermarket. Chef Documentation3.8. Systems Administration61Python Guide Documentation, 发发发布布布 0.0.1PuppetPuppetis ITAutomation andconfigurationmanagement softwarefrom PuppetLabs thatallowsSystem Administratorsto define the st

237、ate of their IT Infrastructure, thereby providing an elegant way to manage their fleet of physical andvirtual machines.Puppet is available both as an Open Source and an Enterprise variant. Modules are small, shareable units of codewritten to automate or define the state of a system. Puppet Forge is

238、a repository for modules written by the communityfor Open Source and Enterprise Puppet.Puppet Agents are installed on nodes whose state needs to be monitored or changed. A designated server known asthe Puppet Master is responsible for orchestrating the agent nodes.Agent nodes send basic facts about

239、the system such as to the operating system, kernel, architecture, ip address, host-name etc. to the Puppet Master. The Puppet Master then compiles a catalog with information provided by the agentson how each node should be configured and sends it to the agent. The agent enforces the change as prescr

240、ibed in thecatalog and sends a report back to the Puppet Master.Facter is an interesting tool that ships with Puppet that pulls basic facts about the system. These facts can be referencedas a variable while writing your Puppet modules.$ facter kernelLinux$ facter operatingsystemUbuntuWriting Modules

241、 in Puppet is pretty straight forward. Puppet Manifests together form Puppet Modules. Puppetmanifest end with an extension of .pp. Here is an example of Hello World in Puppet.notify This message is getting logged into the agent node:#As nothing is specified in the body the resource title#the notific

242、ation message by default.Here is another example with system based logic. Note how the operating system fact is being used as a variableprepended with the $ sign. Similarly, this holds true for other facts such as hostname which can be referenced by$hostnamenotify Mac Warning:message = $operatingsys

243、tem ? Darwin = This seems to be a Mac.,default= I am a PC.,There are several resource types for Puppet but the package-file-service paradigm is all you need for undertakingmajority of the configuration management. The following Puppet code makes sure that the OpenSSH-Server packageis installed in a

244、system and the sshd service is notified to restart everytime the sshd configuration file is changed.package openssh-server:ensure = installed,file /etc/ssh/sshd_config:source= puppet:/modules/sshd/sshd_config,owner= root,group= root,mode= 640,62Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation

245、, 发发发布布布 0.0.1notify=Servicesshd, # sshd will restart# whenever you edit this# filerequire= Packageopenssh-server,service sshd:ensure= running,enable= true,hasstatus = true,hasrestart= true,For more information, refer to the Puppet Labs DocumentationBlueprint待待待处处处理理理Write about BlueprintBuildoutBui

246、ldout is an open source software build tool. Buildout is created using the Python programming language. Itimplements a principle of separation of configuration from the scripts that do the setting up. Buildout is primarily usedto download and set up dependencies in Python eggs format of the software

247、 being developed or deployed. Recipes forbuild tasks in any environment can be created, and many are already available.ShinkenShinken is a modern, Nagios compatible monitoring framework written in Python. Its main goal is to give users aflexible architecture for their monitoring system that is desig

248、ned to scale to large environments.Shinken is backwards-compatible with the Nagios configuration standard, and plugins.It works on any operating sys-tem, and architecture that supports Python which includes Windows, GNU/Linux, and FreeBSD.Continuous IntegrationWhy?Martin Fowler, who first wrote abou

249、t Continuous Integration (short: CI) together with Kent Beck, describes the CI asfollows:Continuous Integration is a software development practice where members of a team integrate their workfrequently, usually each person integrates at least daily - leading to multiple integrations per day. Eachint

250、egration is verified by an automated build (including test) to detect integration errors as quickly aspossible. Many teams find that this approach leads to significantly reduced integration problems andallows a team to develop cohesive software more rapidly.3.9. Continuous Integration63Python Guide

251、Documentation, 发发发布布布 0.0.1JenkinsJenkins CI is an extensible continuous integration engine. Use it.BuildbotBuildbot is a Python system to automate the compile/test cycle to validate code changes.Toxtox is an automation tool providing packaging, testing and deployment of Python software right from t

252、he console orCI server. It is a generic virtualenv management and test command line tool which provides the following features: Checking that packages install correctly with different Python versions and interpreters Running tests in each of the environments, configuring your test tool of choice Act

253、ing as a front-end to Continuous Integration servers, reducing boilerplate and merging CI and shell-basedtesting.Travis-CITravis-CI is a distributed CI server which builds tests for open source projects for free. It provides multiple workersto run Python tests on and seamlessly integrates with GitHu

254、b. You can even have it comment on your Pull Requestswhether this particular changeset breaks the build or not. So if you are hosting your code on GitHub, travis-ci is agreat and easy way to get started with Continuous Integration.In order to get started, add a .travis.yml file to your repository wi

255、th this example content:language: pythonpython:- 2.6- 2.7- 3.2- 3.3# command to install dependenciesscript: python tests/test_all_of_the_units.pybranches:only:- masterThis will get your project tested on all the listed Python versions by running the given script, and will only build themaster branch

256、. There are a lot more options you can enable, like notifications, before and after steps and much more.The travis-ci docs explain all of these options, and are very thorough.In order to activate testing for your project, go to the travis-ci site and login with your GitHub account. Then activateyour

257、 project in your profile settings and youre ready to go. From now on, your projects tests will be run on everypush to GitHub.SpeedCPython, the most commonly used implementation of Python, is slow for CPU bound tasks. PyPy is fast.64Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.

258、1Using a slightly modified version of David Beazleys CPU bound test code (added loop for multiple tests), you cansee the difference between CPython and PyPys processing.# PyPy$ ./pypy -VPython 2.7.1 (7773f8fc4223, Nov 18 2011, 18:47:10)PyPy 1.7.0 with GCC 4.4.3$ ./pypy measure2.py0.06839990615840.04

259、832100868230.03885889053340.04406905174260.0695300102234# CPython$ ./python -VPython 2.7.1$ ./python measure2.py1.067744016651.454123973851.514852046971.546938896181.60109114647ContextThe GILThe GIL (Global Interpreter Lock) is how Python allows multiple threads to operate at the same time. Pythonsm

260、emory management isnt entirely thread-safe, so the GIL is required to prevent multiple threads from running thesame Python code at once.David Beazley has a great guide on how the GIL operates. He also covers the new GIL in Python 3.2. His results showthat maximizing performance in a Python applicati

261、on requires a strong understanding of the GIL, how it affects yourspecific application, how many cores you have, and where your application bottlenecks are.C ExtensionsThe GILSpecial care must be taken when writing C extensions to make sure you register your threads with the interpreter.C Extensions

262、CythonCython implements a superset of the Python language with which you are able to write C and C+ modules for Python.Cython also allows you to call functions from compiled C libraries. Using Cython allows you to take advantage ofPythons strong typing of variables and operations.Heres an example of

263、 strong typing with Cython:3.10. Speed65Python Guide Documentation, 发发发布布布 0.0.1def primes(int kmax):Calculation of prime numbers with additionalCython keywordscdef int n, k, icdef int p1000result = if kmax 1000:kmax = 1000k = 0n = 2while k kmax:i = 0while i 1000:kmax = 1000k = 0n = 2while k kmax:i

264、= 0while i k and n % pi != 0:i = i + 1if i = k:pk = nk = k + 1result.append(n)n = n + 1return resultNotice that in the Cython version you declare integers and integer arrays to be compiled into C types while alsocreating a Python list:def primes(int kmax):Calculation of prime numbers with additional

265、Cython keywordscdef int n, k, icdef int p1000result = def primes(kmax):Calculation of prime numbers in standard Python syntax66Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1p = range(1000)result = What is the difference? In the upper Cython version you can see the declaration

266、of the variable types and the integerarrayinasimilarwayasinstandardC.Forexamplecdefintn,k,iinline3. Thisadditionaltypedeclaration(i.e. integer)allows the Cython compiler to generate more efficient C code from the second version. While standard Python codeis saved in*.py files, Cython code is saved i

267、n*.pyx files.Whats the difference in speed? Lets try it!import time#activate pyx compilerimport pyximportpyximport.install()#primes implemented with Cythonimport primesCy#primes implemented with Pythonimport primesprint Cython:t1= time.time()print primesCy.primes(500)t2= time.time()print Cython time

268、: %s %(t2-t1)print print Pythont1= time.time()print primes.primes(500)t2= time.time()print Python time: %s %(t2-t1)These lines both need a remark:import pyximportpyximport.install()The pyximport module allows you to import*.pyx files (e.g., primesCy.pyx) with the Cython-compiled versionof the primes

269、 function. The pyximport.install() command allows the Python interpreter to start the Cython compilerdirectly to generate C-code, which is automatically compiled to a*.so C-library. Cython is then able to import thislibrary for you in your Python code, easily and efficiently. With the time.time() fu

270、nction you are able to compare thetime between these 2 different calls to find 500 prime numbers. On a standard notebook (dual core AMD E-450 1.6GHz), the measured values are:Cython time: 0.0054 secondsPython time: 0.0566 secondsAnd here the output of an embedded ARM beaglebone machine:Cython time:

271、0.0196 secondsPython time: 0.3302 secondsPyrex3.10. Speed67Python Guide Documentation, 发发发布布布 0.0.1Shedskin?ConcurrencyConcurrent.futuresThe concurrent.futures module is a module in the standard library that provides a “high-level interface for asyn-chronously executing callables”. It abstracts away

272、 a lot of the more complicated details about using multiple threadsor processes for concurrency, and allows the user to focus on accomplishing the task at hand.The concurrent.futures module exposes two main classes, the ThreadPoolExecutor and the ProcessPoolExecutor. TheThreadPoolExecutor will creat

273、e a pool of worker threads that a user can submit jobs to. These jobs will then beexecuted in another thread when the next worker thread becomes available.The ProcessPoolExecutor works in the same way, except instead of using multiple threads for its workers, it will usemultiple processes. This make

274、s it possible to side-step the GIL, however because of the way things are passed toworker processes, only picklable objects can be executed and returned.Because of the way the GIL works, a good rule of thumb is to use a ThreadPoolExecutor when the task being executedinvolves a lot of blocking (i.e.

275、making requests over the network) and to use a ProcessPoolExecutor executor whenthe task is computationally expensive.There are two main ways of executing things in parallel using the two Executors. One way is with the map(func,iterables) method. This works almost exactly like the builtin map() func

276、tion, except it will execute everything inparallel. :from concurrent.futures import ThreadPoolExecutorimport requestsdef get_webpage(url):page = requests.get(url)return pagepool = ThreadPoolExecutor(max_workers=5)my_urls = http:/ Create a list of urlsfor page in pool.map(get_webpage, my_urls):# Do s

277、omething with the resultprint(page.text)For even more control, the submit(func, *args, *kwargs) method will schedule a callable to be executed ( asfunc(*args, *kwargs) and returns a Future object that represents the execution of the callable.The Future object provides various methods that can be use

278、d to check on the progress of the scheduled callable. Theseinclude:cancel() Attempt to cancel the call.cancelled() Return True if the call was successfully cancelled.running() Return True if the call is currently being executed and cannot be cancelled.done() Return True if the call was successfully

279、cancelled or finished running.result() Return the value returned by the call. Note that this call will block until the scheduled callable returns bydefault.exception() Return the exception raised by the call. If no exception was raised then this returns None. Note that thiswill block just like resul

280、t().68Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1add_done_callback(fn) Attach a callback function that will be executed (as fn(future) when the scheduled callablereturns.from concurrent.futures import ProcessPoolExecutor, as_completeddef is_prime(n):if n % 2 = 0:return n, F

281、alsesqrt_n = int(n*0.5)for i in range(3, sqrt_n + 1, 2):if n % i = 0:return n, Falsereturn n, TruePRIMES = 112272535095293,112582705942171,112272535095293,115280095190773,115797848077099,1099726899285419futures = with ProcessPoolExecutor(max_workers=4) as pool:# Schedule the ProcessPoolExecutor to c

282、heck if a number is prime# and add the returned Future to our list of futuresfor p in PRIMES:fut = pool.submit(is_prime, p)futures.append(fut)# As the jobs are completed, print out the resultsfor number, result in as_completed(futures):if result:print( is prime.format(number)else:print( is not prime

283、.format(number)The concurrent.futures module contains two helper functions for working with Futures. The as_completed(futures)function returns an iterator over the list of futures, yielding the futures as they complete.The wait(futures) function will simply block until all futures in the list of fut

284、ures provided have completed.For more information, on using the concurrent.futures module, consult the official documentation.ThreadingThe standard library comes with a threading module that allows a user to work with multiple threads manually.Running a function in another thread is as simple as pas

285、sing a callable and its arguments to Threads constructor andthen calling start():from threading import Threadimport requestsdef get_webpage(url):page = requests.get(url)return page3.10. Speed69Python Guide Documentation, 发发发布布布 0.0.1some_thread = Thread(get_webpage, http:/ wait until the thread has

286、terminated, call join():some_thread.join()After calling join(), it is always a good idea to check whether the thread is still alive (because the join call timed out):if some_thread.is_alive():print(join() must have timed out.)else:print(Our thread has terminated.)Because multiple threads have access

287、 to the same section of memory, sometimes there might be situations where twoor more threads are trying to write to the same resource at the same time or where the output is dependent on thesequence or timing of certain events. This is called a data race or race condition. When this happens, the out

288、put willbe garbled or you may encounter problems which are difficult to debug. A good example is this stackoverflow post.The way this can be avoided is by using a Lock_ that each thread needs to acquire before writing to a shared resource.Locks can be acquired and released through either the context

289、manager protocol (with statement), or by using acquire()and release() directly. Here is a (rather contrived) example:from threading import Lock, Threadfile_lock = Lock()def log(msg):with file_lock:open(website_changes.log, w) as f:f.write(changes)def monitor_website(some_website):Monitor a website a

290、nd then if there are any changes,log them to disk.while True:changes = check_for_changes(some_website)if changes:log(changes)websites = http:/ . for website in websites:t = Thread(monitor_website, website)t.start()Here, we have a bunch of threads checking for changes on a list of sites and whenever

291、there are any changes, theyattempt to write those changes to a file by calling log(changes). When log() is called, it will wait to acquire the lockwith with file_lock:. This ensures that at any one time, only one thread is writing to the file.Spawning Processes70Chapter 3. Python应应应用用用场场场景景景Python G

292、uide Documentation, 发发发布布布 0.0.1MultiprocessingScientific ApplicationsContextPython is frequently used for high-performance scientific applications. It is widely used in academia and scientificprojects because it is easy to write and performs well.Due to its high performance nature, scientific compu

293、ting in Python often utilizes external libraries, typically writtenin faster languages (like C, or FORTRAN for matrix operations). The main libraries used are NumPy, SciPy andMatplotlib. Going into detail about these libraries is beyond the scope of the Python guide. However, a comprehensiveintroduc

294、tion to the scientific Python ecosystem can be found in the Python Scientific Lecture NotesToolsIPythonIPython is an enhanced version of Python interpreter, which provides features of great interest to scientists. The inlinemode allows graphics and plots to be displayed in the terminal (Qt based ver

295、sion). Moreover, the notebook mode sup-ports literate programming and reproducible science generating a web-based Python notebook. This notebook allowsyou to store chunks of Python code along side the results and additional comments (HTML, LaTeX, Markdown). Thenotebook can then be shared and exporte

296、d in various file formats.LibrariesNumPyNumPy is a low level library written in C (and FORTRAN) for high level mathematical functions. NumPy cleverlyovercomes the problem of running slower algorithms on Python by using multidimensional arrays and functions thatoperate on arrays. Any algorithm can th

297、en be expressed as a function on arrays, allowing the algorithms to be runquickly.NumPy is part of the SciPy project, and is released as a separate library so people who only need the basic requirementscan use it without installing the rest of SciPy.NumPy is compatible with Python versions 2.4 throu

298、gh to 2.7.2 and 3.1+.NumbaNumbaisaNumPyawarePythoncompiler(just-in-time(JIT)specializingcompiler)whichcompilesannotatedPython(and NumPy) code to LLVM (Low Level Virtual Machine) through special decorators. Briefly, Numba uses a systemthat compiles Python code with LLVM to code which can be natively

299、executed at runtime.SciPySciPy is a library that uses NumPy for more mathematical functions. SciPy uses NumPy arrays as the basic data struc-ture, and comes with modules for various commonly used tasks in scientific programming, including linear algebra,integration (calculus), ordinary differential

300、equation solving and signal processing.3.11. Scientific Applications71Python Guide Documentation, 发发发布布布 0.0.1MatplotlibMatplotlib is a flexible plotting library for creating interactive 2D and 3D plots that can also be saved as manuscript-quality figures. The API in many ways reflects that of MATLA

301、B, easing transition of MATLAB users to Python.Many examples, along with the source code to re-create them, are available in the matplotlib gallery.PandasPandas is data manipulation library based on Numpy which provides many useful functions for accessing, indexing,merging and grouping data easily.

302、The main data structure (DataFrame) is close to what could be found in the Rstatistical package; that is, heterogeneous data tables with name indexing, time series operations and auto-alignmentof data.Rpy2Rpy2 is a Python binding for the R statistical package allowing the execution of R functions fr

303、om Python and passingdata back and forth between the two environments. Rpy2 is the object oriented implementation of the Rpy bindings.PsychoPyPsychoPy is a library for cognitive scientists allowing the creation of cognitive psychology and neuroscience experi-ments. The library handles presentation o

304、f stimuli, scripting of experimental design and data collection.ResourcesInstallation of scientific Python packages can be troublesome, as many of these packages are implemented as PythonC extensions which need to be compiled. This section lists various so-called scientific Python distributions whic

305、hprovide precompiled and easy-to-install collections of scientific Python packages.Unofficial Windows Binaries for Python Extension PackagesMany people who do scientific computing are on Windows, yet many of the scientific computing packages are no-toriously difficult to build and install on this pl

306、atform. Christoph Gohlke however, has compiled a list of Windowsbinaries for many useful Python packages. The list of packages has grown from a mainly scientific Python resource toa more general list. If youre on Windows, you may want to check it out.AnacondaContinuum Analytics offers the Anaconda P

307、ython Distribution which includes all the common scientific Python pack-ages as well as many packages related to data analytics and big data. Anaconda itself is free, and Continuum sells anumber of proprietary add-ons. Free licenses for the add-ons are available for academics and researchers.CanopyC

308、anopy is another scientific Python distribution, produced by Enthought. A limited Canopy Express variant isavailable for free, but Enthought charges for the full distribution. Free licenses are available for academics.72Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1Image Manip

309、ulationMost image processing and manipulation techniques can be carried out effectively using two libraries: Python ImagingLibrary (PIL) and OpenSource Computer Vision (OpenCV).A brief description of both is given below.Python Imaging LibraryThe Python Imaging Library, or PIL for short, is one of th

310、e core libraries for image manipulation in Python. Unfortu-nately, its development has stagnated, with its last release in 2009.Luckily for you, theres an actively-developed fork of PIL called Pillow - its easier to install, runs on all operatingsystems, and supports Python 3.InstallationBefore inst

311、alling Pillow, youll have to install Pillows prerequisites. Find the instructions for your platform in thePillow installation instructions.After that, its straightforward:$ pip install PillowExamplefrom PIL import Image, ImageFilter#Read imageim = Image.open( image.jpg )#Display imageim.show()#Apply

312、ing a filter to the imageim_sharp = im.filter( ImageFilter.SHARPEN )#Saving the filtered image to a new fileim_sharp.save( image_sharpened.jpg, JPEG )#Splitting the image into its respective bands, i.e. Red, Green,#and Blue for RGBr,g,b = im_sharp.split()#Viewing EXIF data embedded in imageexif_data

313、 = im._getexif()exif_dataThere are more examples of the Pillow library in the Pillow tutorial.OpenSource Computer VisionOpenSource Computer Vision, more commonly known as OpenCV, is a more advanced image manipulation andprocessing software than PIL. It has been implemented in several languages and i

314、s widely used.3.12. Image Manipulation73Python Guide Documentation, 发发发布布布 0.0.1InstallationIn Python, image processing using OpenCV is implemented using the cv2 and NumPy modules. The installationinstructions for OpenCV should guide you through configuring the project for yourself.NumPy can be down

315、loaded from the Python Package Index(PyPI):$ pip install numpyExamplefrom cv2 import*import numpy as np#Read Imageimg = cv2.imread(testimg.jpg)#Display Imagecv2.imshow(image,img)cv2.waitKey(0)cv2.destroyAllWindows()#Applying Grayscale filter to imagegray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY)#Savin

316、g filtered image to new filecv2.imwrite(graytest.jpg,gray)There are more Python-implemented examples of OpenCV in this collection of tutorials.Data SerializationWhat is data serialization?Data serialization is the concept of converting structured data into a format that allows it to be shared or sto

317、red insuch a way that its original structure to be recovered. In some cases, the secondary intention of data serialization is tominimize the size of the serialized data which then minimizes disk space or bandwidth requirements.PickleThe native data serialization module for Python is called Pickle.He

318、res an example:import pickle#Heres an example dictgrades = Alice: 89, Bob: 72, Charles: 87 #Use dumps to convert the object to a serialized stringserial_grades = pickle.dumps( grades )#Use loads to de-serialize an objectreceived_grades = pickle.loads( serial_grades )74Chapter 3. Python应应应用用用场场场景景景Py

319、thon Guide Documentation, 发发发布布布 0.0.1ProtobufIf youre looking for a serialization module that has support in multiple languages, Googles Protobuf library is anoption.XML parsinguntangleuntangle is a simple library which takes an XML document and returns a Python object which mirrors the nodes andat

320、tributes in its structure.For example, an XML file like this:can be loaded like this:import untangleobj = untangle.parse(path/to/file.xml)and then you can get the child elements name like this:obj.root.childnameuntangle also supports loading XML from a string or an URL.xmltodictxmltodict is another

321、simple library that aims at making XML feel like working with JSON.An XML file like this:elementsmore elementselement as wellcan be loaded into a Python dict like this:import xmltodictwith open(path/to/file.xml) as fd:doc = xmltodict.parse(fd.read()and then you can access elements, attributes and va

322、lues like this:3.14. XML parsing75Python Guide Documentation, 发发发布布布 0.0.1docmydocumenthas # = uan attributedocmydocumentandmany # = uelements, umore elementsdocmydocumentplusa # = ucomplexdocmydocumentplus#text # = uelement as wellxmltodict also lets you roundtrip back to XML with the unparse funct

323、ion, has a streaming mode suitable for handlingfiles that dont fit in memory and supports namespaces.JSONThe json library can parse JSON from strings or files. The library parses JSON into a Python dictionary or list. It canalso convert Python dictionaries or lists into JSON strings.Parsing JSONTake

324、 the following string containing JSON data:json_string = first_name: Guido, last_name:RossumIt can be parsed like this:import jsonparsed_json = json.loads(json_string)and can now be used as a normal dictionary:print(parsed_jsonfirst_name)GuidoYou can also convert the following to JSON:d = first_name

325、: Guido,second_name: Rossum,titles: BDFL, Developer,print(json.dumps(d)first_name: Guido, last_name: Rossum, titles: BDFL, DevelopersimplejsonThe JSON library was added to Python in version 2.6. If youre using an earlier version of Python, the simplejsonlibrary is available via PyPI.simplejson mimic

326、s the json standard library. It is available so that developers that use older versions of Python can usethe latest features available in the json lib.You can start using simplejson when the json library is not available by importing simplejson under a different name:import simplejson as jsonAfter i

327、mporting simplejson as json, the above examples will all work as if you were using the standard json library.76Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1CryptographyCryptographyCryptography is an actively developed library that provides cryptographic recipes and primitives

328、. It supports Python2.6-2.7, Python 3.3+ and PyPy.Cryptography is divided into two layers of recipes and hazardous materials (hazmat). The recipes layer providessimple API for proper symmetric encryption and the hazmat layer provides low-level cryptographic primitives.Installation$ pip install crypt

329、ographyExampleExample code using high level symmetric encryption recipe:from cryptography.fernet import Fernetkey = Fernet.generate_key()cipher_suite = Fernet(key)cipher_text = cipher_suite.encrypt(bA really secret message. Not for prying eyes.)plain_text = cipher_suite.decrypt(cipher_text)PyCryptoP

330、yCrypto is another library, which provides secure hash functions and various encryption algorithms. It supportsPython version 2.1 through 3.3.Installation$ pip install pycryptoExamplefrom Crypto.Cipher import AES# Encryptionencryption_suite = AES.new(This is a key123, AES.MODE_CBC, This is an IV456)

331、cipher_text = encryption_suite.encrypt(A really secret message. Not for prying eyes.)# Decryptiondecryption_suite = AES.new(This is a key123, AES.MODE_CBC, This is an IV456)plain_text = decryption_suite.decrypt(cipher_text)Machine LearningPython has a vast number of libraries for data analysis, stat

332、istics and Machine Learning itself, making it a language ofchoice for many data scientists.3.16. Cryptography77Python Guide Documentation, 发发发布布布 0.0.1Some widely used packages for Machine Learning and other Data Science applications are enlisted below.Scipy StackThe Scipy stack consists of a bunch

333、of core helper packages used in data science, for statistical analysis and visualisingdata. Because of its huge number of functionalities and ease of use, the Stack is considered a must-have for most datascience applications.The Stack consists of the following packages (link to documentation given):

334、1. NumPy2. SciPy library3. Matplotlib4. IPython5. pandas6. Sympy7. noseThe stack also comes with Python bundled in, but has been excluded from the above list.InstallationFor installing the full stack, or individual packages, you can refer to the instructions given here.NB: Anaconda is highly preferr

335、ed and recommended for installing and maintaining data science packages seamlessly.scikit-learnScikit is a free and open-source machine learning library for Python. It offers off-the-shelf functions to implementmany algorithms like linear regression, classifiers, SVMs, k-means, Neural Networks etc.

336、It also has a few sampledatasets which can be directly used for training and testing.Because of its speed, robustness and easiness to use, its one of the most widely-used libraries for many MachineLearning applications.InstallationThrough PyPI:pip install -U scikit-learnThrough conda:conda install s

337、cikit-learnscikit-learn also comes in shipped with Anaconda (mentioned above). For more installation instructions, refer to thislink.78Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation, 发发发布布布 0.0.1ExampleFor this example, we train a simple classifier on the Iris dataset, which comes bundled i

338、n with scikit-learn.The dataset takes four features of flowers: sepal length, sepal width, petal length and petal width, and classifies theminto three flower species (labels): setosa, versicolor or virginica. The labels have been represented as numbers in thedataset: 0 (setosa), 1 (versicolor) and 2

339、 (virginica).We shuffle the Iris dataset, and divide it into separate training and testing sets: keeping the last 10 data points fortesting and rest for training. We then train the classifier on the training set, and predict on the testing set.from sklearn.datasets import load_irisfrom sklearn impor

340、t treefrom sklearn.metrics import accuracy_scoreimport numpy as np#loading the iris datasetiris = load_iris()x = iris.data #array of the datay = iris.target #array of labels (i.e answers) of each data entry#getting label names i.e the three flower speciesy_names = iris.target_names#taking random ind

341、ices to split the dataset into train and testtest_ids = np.random.permutation(len(x)#splitting data and labels into train and test#keeping last 10 entries for testing, rest for trainingx_train = xtest_ids:-10x_test = xtest_ids-10:y_train = ytest_ids:-10y_test = ytest_ids-10:#classifying using decisi

342、on treeclf = tree.DecisionTreeClassifier()#training (fitting) the classifier with the training setclf.fit(x_train, y_train)#predictions on the test datasetpred = clf.predict(x_test)print pred #predicted labels i.e flower speciesprint y_test #actual labelsprint (accuracy_score(pred, y_test)*100 #pred

343、iction accuracySince were splitting randomly and the classifier trains on every iteration, the accuracy may vary. Running the abovecode gives:0 1 1 1 0 2 0 2 2 20 1 1 1 0 2 0 2 2 2100.0The first line contains the labels (i.e flower species) of the testing data as predicted by our classifier, and the

344、 secondline contains the actual flower species as given in the dataset. We thus get an accuracy of 100% this time.3.17. Machine Learning79Python Guide Documentation, 发发发布布布 0.0.1More on scikit-learn can be read in the documentation.Interfacing with C/C+ LibrariesC Foreign Function InterfaceCFFI prov

345、ides a simple to use mechanism for interfacing with C from both CPython and PyPy. It supports two modes:an inline ABI compatibility mode (example provided below), which allows you to dynamically load and run functionsfrom executable modules (essentially exposing the same functionality as LoadLibrary

346、 or dlopen), and an API mode,which allows you to build C extension modules.ABI Interaction1from cffi import FFI2ffi = FFI()3ffi.cdef(size_t strlen(const char*);)4clib = ffi.dlopen(None)5length = clib.strlen(String to be evaluated.)6# prints: 237print(.format(length)ctypesctypes is the de facto libra

347、ry for interfacing with C/C+ from CPython, and it provides not only full access to thenative C interface of most major operating systems (e.g., kernel32 on Windows, or libc on *nix), but also providessupport for loading and interfacing with dynamic libraries, such as DLLs or shared objects at runtim

348、e. It does bringalong with it a whole host of types for interacting with system APIs, and allows you to rather easily define your owncomplex types, such as structs and unions, and allows you to modify things such as padding and alignment, if needed.It can be a bit crufty to use, but in conjunction w

349、ith the struct module, you are essentially provided full control overhow your data types get translated into something usable by a pure C(+) method.Struct EquivalentsMyStruct.h1struct my_struct 2int a;3int b;4;MyStruct.py1import ctypes2class my_struct(ctypes.Structure):3_fields_ = (a, c_int),4(b, c_

350、int)SWIGSWIG, though not strictly Python focused (it supports a large number of scripting languages), is a tool for generatingbindings for interpreted languages from C/C+ header files. It is extremely simple to use: the consumer simply needs80Chapter 3. Python应应应用用用场场场景景景Python Guide Documentation,

351、发发发布布布 0.0.1to define an interface file (detailed in the tutorial and documentations), include the requisite C/C+ headers, and runthe build tool against them. While it does have some limits, (it currently seems to have issues with a small subset ofnewer C+ features, and getting template-heavy code t

352、o work can be a bit verbose), it provides a great deal of powerand exposes lots of features to Python with little effort. Additionally, you can easily extend the bindings SWIG creates(in the interface file) to overload operators and built-in methods, effectively re- cast C+ exceptions to be catchabl

353、e byPython, etc.Example: Overloading _repr_MyClass.h1#include 2class MyClass 3private:4std:string name;5public:6std:string getName();7;myclass.i1%include string.i23%module myclass4%5#include 6#include MyClass.h7%89%extend MyClass 10std:string _repr_()1112return $self-getName();13141516%include MyCla

354、ss.hBoost.PythonBoost.Python requires a bit more manual work to expose C+ object functionality, but it is capable of providing allthe same features SWIG does and then some, to include providing wrappers to access PyObjects in C+, extractingSWIG- wrapper objects, and even embedding bits of Python int

355、o your C+ code.3.18. Interfacing with C/C+ Libraries81Python Guide Documentation, 发发发布布布 0.0.182Chapter 3. Python应应应用用用场场场景景景CHAPTER4Python代代代码码码打打打包包包本章主要聚焦于Python代码的部署。Packaging Your CodePackage your code to share it with other developers. For example to share a library for other developers to use

356、 in theirapplication, or for development tools like py.test.An advantage of this method of distribution is its well established ecosystem of tools such as PyPI and pip, whichmake it easy for other developers to download and install your package either for casual experiments, or as part oflarge, prof

357、essional systems.It is a well-established convention for Python code to be shared this way. If your code isnt packaged on PyPI, thenit will be harder for other developers to find it, and to use it as part of their existing process. They will regard suchprojects with substantial suspicion of being ei

358、ther badly managed or abandoned.The downside of distributing code like this is that it relies on the recipient understanding how to install the requiredversion of Python, and being able and willing to use tools such as pip to install your codes other dependencies. This isfine when distributing to ot

359、her developers, but makes this method unsuitable for distributing applications to end-users.The Python Packaging Guide provides an extensive guide on creating and maintaining Python packages.Alternatives to PackagingTo distribute applications to end-users, you should freeze your application.On Linux

360、, you may also want to consider creating a Linux distro package (e.g. a .deb file for Debian or Ubuntu.)For Python DevelopersIf youre writing an open source Python module, PyPI , more properly known as The Cheeseshop, is the place to hostit.Pip vs. easy_installUse pip. More details here83Python Guid

361、e Documentation, 发发发布布布 0.0.1Personal PyPIIf you want to install packages from a source other than PyPI, (say, if your packages are proprietary), you can do it byhosting a simple http server, running from the directory which holds those packages which need to be installed.Showing an example is alway

362、s beneficialFor example, if you want to install a package called MyPackage.tar.gz, and assuming this is your directorystructure: archive MyPackage*MyPackage.tar.gzGo to your command prompt and type:$ cd archive$ python -m SimpleHTTPServer 9000This runs a simple http server running on port 9000 and w

363、ill list all packages (like MyPackage). Now you can installMyPackage using any Python package installer. Using Pip, you would do it like:$ pip install -extra-index-url=http:/127.0.0.1:9000/ MyPackageHaving a folder with the same name as the package name is crucial here. I got fooled by that, one tim

364、e. But if youfeel that creating a folder called MyPackage and keeping MyPackage.tar.gz inside that, is redundant, you canstill install MyPackage using:$ pip installhttp:/127.0.0.1:9000/MyPackage.tar.gzpypiserverPypiserver is a minimal PyPI compatible server. It can be used to serve a set of packages

365、 to easy_install or pip. Itincludes helpful features like an administrativecommand (-U) which will update all its packages to their latest versionsfound on PyPI.S3-Hosted PyPiOne simple option for a personal PyPi server is to use Amazon S3. A prerequisite for this is that you have an AmazonAWS accou

366、nt with an S3 bucket.1. Install all your requirements from PyPi or another source2. Install pip2pi pip install git+https:/ Follow pip2pi README for pip2tgz and dir2pi commands pip2tgz packages/ YourPackage (or pip2tgz packages/ -r requirements.txt) dir2pi packages/4. Upload the new files Use a clien

367、t like Cyberduck to sync the entire packages folder to your s3 bucket Make sure you upload packages/simple/index.html as well as all new files and directories84Chapter 4. Python代代代码码码打打打包包包Python Guide Documentation, 发发发布布布 0.0.15. Fix new file permissions By default, when you upload new files to th

368、e S3 bucket, they will have the wrong permissions set. Use the Amazon web console to set the READ permission of the files to EVERYONE. If you get HTTP 403 when trying to install a package, make sure youve set the permissions correctly.6. All done Youcannowinstallyourpackagewithpip install -index-url

369、=http:/your-s3-bucket/packages/simple/YourPackageFor Linux DistributionsCreating a Linux distro package is arguably the “right way” to distribute code on Linux.Because a distribution package doesnt include the Python interpreter, it makes the download and install about 2MBsmaller than freezing your

370、application.Also, if a distribution releases a new security update for Python, then your application will automatically start usingthat new version of Python.The bdist_rpm command makes producing an RPM file for use by distributions like Red Hat or SuSE is trivially easy.However, creating and mainta

371、ining the different configurations required for each distributions format (e.g. .deb forDebian/Ubuntu, .rpm for Red Hat/Fedora, etc) is a fair amount of work. If your code is an application that you plan todistribute on other platforms, then youll also have to create and maintain the separate config

372、 required to freeze yourapplication for Windows and OSX. It would be much less work to simply create and maintain a single config for oneof the cross platform freezing tools, which will produce stand-alone executables for all distributions of Linux, as wellas Windows and OSX.Creating a distribution

373、package is also problematic if your code is for a version of Python that isnt currently supportedby a distribution. Having to tell some versions of Ubuntu end-users that they need to add the dead-snakes PPA usingsudo apt-repository commands before they can install your .deb file makes for an extreme

374、ly hostile user experience.Not only that, but youd have to maintain a custom equivalent of these instructions for every distribution, and worse,have your users read, understand, and act on them.Having said all that, heres how to do it: Fedora Debian and Ubuntu ArchUseful Tools fpm alien dh-virtualen

375、v (for APT/DEB omnibus packaging)Freezing Your Code“Freezing” your code is creating a single-file executable file to distribute to end-users, that contains all of your appli-cation code as well as the Python interpreter.4.2. Freezing Your Code85Python Guide Documentation, 发发发布布布 0.0.1Applications su

376、ch as Dropbox, Eve Online, Civilization IV, and BitTorrent clients do this.The advantage of distributing this way is that your application will “just work”, even if the user doesnt already havethe required version of Python (or any) installed. On Windows, and even on many Linux distributions and OS

377、X, theright version of Python will not already be installed.Besides, end-user software should always be in an executable format. Files ending in .py are for software engineersand system administrators.One disadvantage of freezing is that it will increase the size of your distribution by about 212MB.

378、 Also, you will beresponsible for shipping updated versions of your application when security vulnerabilities to Python are patched.Alternatives to FreezingPackaging your code is for distributing libraries or tools to other developers.On Linux, an alternative to freezing is to create a Linux distro

379、package (e.g. .deb files for Debian or Ubuntu, or .rpmfiles for Red Hat and SuSE.)待待待处处处理理理Fill in “Freezing Your Code” stubComparison of Freezing ToolsSolutions and platforms/features supported:Solu-tionWin-dowsLinuxOSXPython3Li-censeOne-filemodeZipfileimportEggspkg_resourcessupportbbFreeze yesyesy

380、esnoMITnoyesyesyespy2exeyesnonoyesMITyesyesnonopyIn-stalleryesyesyesyesGPLyesnoyesnocx_Freeze yesyesyesyesPSFnoyesyesnopy2appnonoyesyesMITnoyesyesyes注注注解解解: Freezing Python code on Linux into a Windows executable was only once supported in PyInstaller and laterdropped.注注注解解解: All solutions need MS V

381、isual C+ dll to be installed on target machine, except py2app. Only Pyinstaller makesself-executable exe that bundles the dll when passing -onefile to Configure.py.WindowsbbFreezePrerequisite is to install Python, Setuptools and pywin32 dependency on Windows.待待待处处处理理理86Chapter 4. Python代代代码码码打打打包包包P

382、ython Guide Documentation, 发发发布布布 0.0.1Write steps for most basic .exepy2exePrerequisite is to install Python on Windows.1. Download and install http:/ Write setup.py (List of configuration options):from distutils.core import setupimport py2exesetup(windows=script: foobar.py,)3. (Optionally) include

383、 icon4. (Optionally) one-file mode5. Generate .exe into dist directory:$ python setup.py py2exe6. Provide the Microsoft Visual C runtime DLL. Two options: globally install dll on target machine or distributedll alongside with .exe.PyInstallerPrerequisite is to have installed Python, Setuptools and p

384、ywin32 dependency on Windows. Most basic tutorial ManualOS Xpy2appPyInstallerPyInstaller can be used to build Unix executables and windowed apps on Mac OS X 10.6 (Snow Leopard) or newer.To install PyInstaller, use pip:$ pip install pyinstallerTo create a standard Unix executable, from say script.py,

385、 use:$ pyinstaller script.pyThis creates, a script.spec file, analogous to a make file a build folder, that holds some log files4.2. Freezing Your Code87Python Guide Documentation, 发发发布布布 0.0.1 a dist folder, that holds the main executable script, and some dependent Python libraries,all in the same

386、folder as script.py. PyInstaller puts all the Python libraries used in script.py into the distfolder, so when distributing the executable, distribute the whole dist folder.The script.spec file can be edited to customise the build, with options such as bundling data files with the executable includin

387、g run-time libraries (.dll or .so files) that PyInstaller cant infer automatically adding Python run-time options to the executable,Now script.spec can be run with pyinstaller (instead of using script.py again):$ pyinstaller script.specTo create a standalone windowed OS X application, use the -windo

388、wed option$ pyinstaller -windowed script.specThis creates a script.app in the dist folder. Make sure to use GUI packages in your Python code, like PyQt orPySide, to control the graphical parts of the app.There are several options in script.spec related to Mac OS X app bundles here. For example, to s

389、pecify an iconfor the app, use the icon=pathtoicon.icns option.LinuxbbFreezePyInstaller88Chapter 4. Python代代代码码码打打打包包包CHAPTER5Python开开开发发发环环环境境境本章主要聚焦于Python的开发环境以及编写Python代码工具的最佳实践。Your Development EnvironmentText EditorsJust about anything that can edit plain text will work for writing Python code

390、, however, using a more powerful editormay make your life a bit easier.VimVim is a text editor which uses keyboard shortcuts for editing instead of menus or icons. There are a couple of pluginsand settings for the Vim editor to aid Python development. If you only develop in Python, a good start is t

391、o set thedefault settings for indentation and line-wrapping to values compliant with PEP 8. In your home directory, open a filecalled .vimrc and add the following lines:set textwidth=79 lines longer than 79 columns will be brokenset shiftwidth=4 operation indents 4 columns; unindents 4 columnsset ta

392、bstop=4 a hard TAB displays as 4 columnsset expandtab insert spaces when hitting TABsset softtabstop=4 insert/delete 4 spaces when hitting a TAB/BACKSPACEset shiftround round indent to multiple of shiftwidthset autoindent align the new line indent with the previous lineWith these settings, newlines

393、are inserted after 79 characters and indentation is set to 4 spaces per tab. If you also useVim for other languages, there is a handy plugin called indent, which handles indentation settings for Python sourcefiles.There is also a handy syntax plugin called syntax featuring some improvements over the

394、 syntax file included in Vim6.1.These plugins supply you with a basic environment for developing in Python. To get the most out of Vim, you shouldcontinually check your code for syntax errors and PEP8 compliance. Luckily PEP8 and Pyflakes will do this for you.If your Vim is compiled with +python you

395、 can also utilize some very handy plugins to do these checks from withinthe editor.For PEP8 checking and pyflakes, you can install vim-flake8. Now you can map the function Flake8 to any hotkey oraction you want in Vim. The plugin will display errors at the bottom of the screen, and provide an easy w

396、ay to jump89Python Guide Documentation, 发发发布布布 0.0.1to the corresponding line. Its very handy to call this function whenever you save a file. In order to do this, add thefollowing line to your .vimrc:autocmd BufWritePost*.py call Flake8()If you are already using syntastic, you can set it to run Pyfl

397、akes on write and show errors and warnings in the quickfixwindow. An example configuration to do that which also shows status and warning messages in the statusbar wouldbe:set statusline+=%#warningmsg#set statusline+=%SyntasticStatuslineFlag()set statusline+=%*let g:syntastic_auto_loc_list=1let g:sy

398、ntastic_loc_list_height=5Python-modePython-mode is a complex solution for working with Python code in Vim. It has: Asynchronous Python code checking (pylint, pyflakes, pep8, mccabe) in any combination Code refactoring and autocompletion with Rope Fast Python folding Virtualenv support Search through

399、 Python documentation and run Python code Auto PEP8 error fixesAnd more.SuperTabSuperTab is a small Vim plugin that makes code completion more convenient by using key or any othercustomized keys.EmacsEmacs is another powerful text editor. It is fully programmable (lisp), but it can be some work to w

400、ire up correctly. Agood start if youre already an Emacs user is Python Programming in Emacs at EmacsWiki.1. Emacs itself comes with a Python mode.TextMateTextMate brings Apples approach to operating systems into the world of text editors. By bridging UNIXunderpinnings and GUI, TextMate cherry-picks

401、the best of both worlds to the benefit of expert scriptersand novice users alike.90Chapter 5. Python开开开发发发环环环境境境Python Guide Documentation, 发发发布布布 0.0.1Sublime TextSublime Text is a sophisticated text editor for code, markup and prose. Youll love the slick user interface,extraordinary features and a

402、mazing performance.Sublime Text has excellent support for editing Python code and uses Python for its plugin API. It also has a diversevariety of plugins, some of which allow for in-editor PEP8 checking and code “linting”.AtomAtom is a hackable text editor for the 21st century, built on atom-shell,

403、and based on everything we loveabout our favorite editors.Atom is web native (HTML, CSS, JS), focusing on modular design and easy plugin development. It comes withnative package control and plethora of packages. Recommended for Python development is Linter combined withlinter-flake8.IDEsPyCharm / In

404、telliJ IDEAPyCharm is developed by JetBrains, also known for IntelliJ IDEA. Both share the same code base and most of Py-Charms features can be brought to IntelliJ with the free Python Plug-In. There are two versions of PyCharm: Profes-sional Edition (Free 30-day trial) and Community Edition (Apache

405、 2.0 License) with fewer features.Python (on Visual Studio Code)Python for Visual Studio is an extension for the Visual Studio Code IDE. This is a free, light weight, open source IDE,with support for Mac, Windows, and Linux. Built using open source technologies such as Node.js and Python, withcompel

406、ling features such as Intellisense (autocompletion), local and remote debugging, linting, and the like.MIT licensed.Enthought CanopyEnthought Canopy is a Python IDE which is focused towards Scientists and Engineers as it provides pre installedlibraries for data analysis.EclipseThe most popular Eclip

407、se plugin for Python development is Aptanas PyDev.Komodo IDEKomodo IDE is developed by ActiveState and is a commercial IDE for Windows, Mac, and Linux. KomodoEdit is theopen source alternative.5.1. Your Development Environment91Python Guide Documentation, 发发发布布布 0.0.1SpyderSpyder is an IDE specifica

408、lly geared toward working with scientific Python libraries (namely Scipy). It includesintegration with pyflakes, pylint and rope.Spyder is open-source (free), offers code completion, syntax highlighting, a class and function browser, and objectinspection.WingIDEWingIDE is a Python specific IDE. It r

409、uns on Linux, Windows and Mac (as an X11 application, which frustrates someMac users).WingIDE offers code completion, syntax highlighting, source browser, graphical debugger and support for versioncontrol systems.NINJA-IDENINJA-IDE (from the recursive acronym: “Ninja-IDE Is Not Just Another IDE”) is

410、 a cross-platform IDE, speciallydesigned to build Python applications, and runs on Linux/X11, Mac OS X and Windows desktop operating systems.Installers for these platforms can be downloaded from the website.NINJA-IDE is open-source software (GPLv3 licence) and is developed in Python and Qt. The sour

411、ce files can bedownloaded from GitHub.Eric (The Eric Python IDE)Eric is a full featured Python IDE offering sourcecode autocompletion, syntax highlighting, support for version controlsystems, python 3 support, integrated web browser, python shell, integrated debugger and a flexible plug-in system.Wr

412、itten in python, it is based on the Qt gui toolkit, integrating the Scintilla editor control. Eric is an open-sourcesoftware project (GPLv3 licence) with more than ten years of active development.Interpreter ToolsVirtual EnvironmentsVirtual Environments provide a powerful way to isolate project pack

413、age dependencies. This means that you canuse packages particular to a Python project without installing them system wide and thus avoiding potential versionconflicts.To start using and see more information: Virtual Environments docs.pyenvpyenv is a tool to allow multiple versions of the Python inter

414、preter to be installed at the same time. This solves theproblem of having different projects requiring different versions of Python. For example, it becomes very easy toinstall Python 2.7 for compatibility in one project, whilst still using Python 3.4 as the default interpreter. pyenv isntjust limit

415、ed to the CPython versions - it will also install PyPy, anaconda, miniconda, stackless, jython, and ironpythoninterpreters.pyenv works by filling a shims directory with fake versions of the Python interpreter (plus other tools like pip and2to3). When the system looks for a program named python, it l

416、ooks inside the shims directory first, and uses the92Chapter 5. Python开开开发发发环环环境境境Python Guide Documentation, 发发发布布布 0.0.1fake version, which in turn passes the command on to pyenv. pyenv then works out which version of Python shouldbe run based on environment variables, .python-version files, and t

417、he global default.pyenv isnt a tool for managing virtual environments, but there is the plugin pyenv-virtualenv which automates thecreation of different environments, and also makes it possible to use the existing pyenv tools to switch to differentenvironments based on environment variables or .pyth

418、on-version files.Other ToolsIDLEIDLE is an integrated development environment that is part of Python standard library. It is completely written inPython and uses the Tkinter GUI toolkit. Though IDLE is not suited for full-blown development using Python, it isquite helpful to try out small Python sni

419、ppets and experiment with different features in Python.It provides the following features: Python Shell Window (interpreter) Multi window text editor that colorizes Python code Minimal debugging facilityIPythonIPython provides a rich toolkit to help you make the most out of using Python interactivel

420、y. Its main components are: Powerful Python shells (terminal- and Qt-based). A web-based notebook with the same core features but support for rich media, text, code, mathematical expres-sions and inline plots. Support for interactive data visualization and use of GUI toolkits. Flexible, embeddable i

421、nterpreters to load into your own projects. Tools for high level and interactive parallel computing.$ pip install ipythonTo download and install IPython with all its optional dependencies for the notebook, qtconsole, tests, and otherfunctionalities$ pip install ipythonallBPythonbpython is an alterna

422、tive interface to the Python interpreter for Unix-like operating systems. It has the followingfeatures: In-line syntax highlighting. Readline-like autocomplete with suggestions displayed as you type. Expected parameter list for any Python function. “Rewind” function to pop the last line of code from

423、 memory and re-evaluate. Send entered code off to a pastebin.5.1. Your Development Environment93Python Guide Documentation, 发发发布布布 0.0.1 Save entered code to a file. Auto-indentation. Python 3 support.$ pip install bpythonptpythonptpython is a REPL build on top of the prompt_toolkit library. It is c

424、onsidered to be an alternative to BPython. Featuresinclude: Syntax highlighting Autocompletion Multiline editing Emacs and VIM Mode Embedding REPL inside of your code Syntax Validation Tab pages Support for integrating with IPythons shell, by installing IPython pip install ipython and runningptipyth

425、on.$ pip install ptpythonVirtual EnvironmentsA Virtual Environment is a tool to keep the dependencies required by different projects in separate places, by creatingvirtual Python environments for them. It solves the “Project X depends on version 1.x but, Project Y needs 4.x”dilemma, and keeps your g

426、lobal site-packages directory clean and manageable.For example, you can work on a project which requires Django 1.10 while also maintaining a project which requiresDjango 1.8.virtualenvvirtualenv is a tool to create isolated Python environments. virtualenv creates a folder which contains all the nec

427、essaryexecutables to use the packages that a Python project would need.Install virtualenv via pip:$ pip install virtualenvBasic Usage1. Create a virtual environment for a project:$ cd my_project_folder$ virtualenv venv94Chapter 5. Python开开开发发发环环环境境境Python Guide Documentation, 发发发布布布 0.0.1virtualenv

428、venv will create a folder in the current directory which will contain the Python executable files, anda copy of the pip library which you can use to install other packages. The name of the virtual environment (in thiscase, it was venv) can be anything; omitting the name will place the files in the c

429、urrent directory instead.This creates a copy of Python in whichever directory you ran the command in, placing it in a folder named venv.You can also use the Python interpreter of your choice (like python2.7).$ virtualenv -p /usr/bin/python2.7 venvor change the interpreter globally with an env variab

430、le in /.bashrc:$ export VIRTUALENVWRAPPER_PYTHON=/usr/bin/python2.72. To begin using the virtual environment, it needs to be activated:$ source venv/bin/activateThenameofthecurrentvirtualenvironmentwillnowappearontheleftoftheprompt(e.g.(venv)Your-Computer:your_project UserName$) to let you know that

431、 its active.From now on,any package that you install using pip will be placed in the venv folder, isolated from the global Python installation.Install packages as usual, for example:$ pip install requests3. If you are done working in the virtual environment for the moment, you can deactivate it:$ de

432、activateThis puts you back to the systems default Python interpreter with all its installed libraries.To delete a virtual environment, just delete its folder. (In this case, it would be rm -rf venv.)After a while, though, you might end up with a lot of virtual environments littered across your syste

433、m, and its possibleyoull forget their names or where they were placed.Other NotesRunning virtualenv with the option -no-site-packages will not include the packages that are installedglobally. This can be useful for keeping the package list clean in case it needs to be accessed later. This is the def

434、aultbehavior for virtualenv 1.7 and later.In order to keep your environment consistent, its a good idea to “freeze” the current state of the environment packages.To do this, run$ pip freeze requirements.txtThis will create a requirements.txt file, which contains a simple list of all the packages in

435、the current environ-ment, and their respective versions. You can see the list of installed packages without the requirements format using“pip list”. Later it will be easier for a different developer (or you, if you need to re-create the environment) to installthe same packages using the same version

436、s:$ pip install -r requirements.txtThis can help ensure consistency across installations, across deployments, and across developers.Lastly, remember to exclude the virtual environment folder from source control by adding it to the ignore list.5.2. Virtual Environments95Python Guide Documentation, 发发

437、发布布布 0.0.1virtualenvwrappervirtualenvwrapper provides a set of commands which makes working with virtual environments much more pleasant.It also places all your virtual environments in one place.To install (make sure virtualenv is already installed):$ pip install virtualenvwrapper$ export WORKON_HOM

438、E=/Envs$ source /usr/local/bin/virtualenvwrapper.sh(Full virtualenvwrapper install instructions.)For Windows, you can use the virtualenvwrapper-win.To install (make sure virtualenv is already installed):$ pip install virtualenvwrapper-winIn Windows, the default path for WORKON_HOME is %USERPROFILE%E

439、nvsBasic Usage1. Create a virtual environment:$ mkvirtualenv venvThis creates the venv folder inside /Envs.2. Work on a virtual environment:$ workon venvAlternatively, you can make a project, which creates the virtual environment, and also a project directory inside$PROJECT_HOME, which is cd -ed int

440、o when you workon myproject.$ mkproject myprojectvirtualenvwrapper provides tab-completion on environment names. It really helps when you have a lot of environ-ments and have trouble remembering their names.workonalsodeactivateswhatever environmentyouarecurrently in, soyoucan quicklyswitchbetweenenv

441、ironments.3. Deactivating is still the same:$ deactivate4. To delete:$ rmvirtualenv venvOther useful commandslsvirtualenv List all of the environments.cdvirtualenv Navigate into the directory of the currently activated virtual environment, so you can browse itssite-packages, for example.cdsitepackag

442、es Like the above, but directly into site-packages directory.lssitepackages Shows contents of site-packages directory.96Chapter 5. Python开开开发发发环环环境境境Python Guide Documentation, 发发发布布布 0.0.1Full list of virtualenvwrapper commands.virtualenv-burritoWith virtualenv-burrito, you can have a working virtu

443、alenv + virtualenvwrapper environment in a single command.autoenvWhen you cd into a directory containing a .env, autoenv automagically activates the environment.Install it on Mac OS X using brew:$ brew install autoenvAnd on Linux:$ git clone git:/ /.autoenv$ echo source /.autoenv/activate.sh /.bashr

444、cFurther Configuration of Pip and VirtualenvRequiring an active virtual environment for pipBy now it should be clear that using virtual environments is a great way to keep your development environment cleanand keeping different projects requirements separate.When you start working on many different

445、projects, it can be hard to remember to activate the related virtual environ-ment when you come back to a specific project. As a result of this, it is very easy to install packages globally whilethinking that you are actually installing the package for the virtual environment of the project. Over ti

446、me this canresult in a messy global package list.In order to make sure that you install packages to your active virtual environment when you use pip install,consider adding the following line to your /.bashrc file:export PIP_REQUIRE_VIRTUALENV=trueAfter saving this change and sourcing the /.bashrc f

447、ile with source /.bashrc, pip will no longer let you in-stall packages if you are not in a virtual environment. If you try to use pip install outside of a virtual environmentpip will gently remind you that an activated virtual environment is needed to install packages.$ pip install requestsCould not

448、 find an activated virtualenv (required).You can also do this configuration by editing your pip.conf or pip.ini file. pip.conf is used by Unix andMac OS X operating systems and it can be found at:$HOME/.pip/pip.confSimilarly, the pip.ini file is used by Windows operating systems and it can be found

449、at:%HOME%pippip.iniIf you dont have a pip.conf or pip.ini file at these locations, you can create a new file with the correct namefor your operating system.5.3. Further Configuration of Pip and Virtualenv97Python Guide Documentation, 发发发布布布 0.0.1If you already have a configuration file, just add the

450、 following line under the global settings to require an activevirtual environment:require-virtualenv = trueIf you did not have a configuration file, you will need to create a new one and add the following lines to this new file:globalrequire-virtualenv = trueYou will of course need to install some p

451、ackages globally (usually ones that you use across different projects consis-tently) and this can be accomplished by adding the following to your /.bashrc file:gpip() PIP_REQUIRE_VIRTUALENV= pip $After saving the changes and sourcing your /.bashrc file you can now install packages globally by runnin

452、g gpipinstall. You can change the name of the function to anything you like, just keep in mind that you will have to usethat name when trying to install packages globally with pip.Caching packages for future useEvery developer has preferred libraries and when you are working on a lot of different pr

453、ojects, you are bound to havesome overlap between the libraries that you use. For example, you may be using the requests library in a lot ofdifferent projects.It is surely unnecessary to re-download the same packages/libraries each time you start working on a new project (andin a new virtual environ

454、ment as a result). Fortunately, you can configure pip in such a way that it tries to reuse alreadyinstalled packages.On UNIX systems, you can add the following line to your .bashrc or .bash_profile file.export PIP_DOWNLOAD_CACHE=$HOME/.pip/cacheYou can set the path to anywhere you like (as long as y

455、ou have write access). After adding this line, source your.bashrc (or .bash_profile) file and you will be all set.Another way of doing the same configuration is via the pip.conf or pip.ini files, depending on your system. Ifyou are on Windows, you can add the following line to your pip.ini file unde

456、r global settings:download-cache = %HOME%pipcacheSimilarly, on UNIX systems you should simply add the following line to your pip.conf file under globalsettings:download-cache = $HOME/.pip/cacheEven though you can use any path you like to store your cache, it is recommended that you create a new fold

457、er in thefolder where your pip.conf or pip.ini file lives. If you dont trust yourself with all of this path voodoo, just usethe values provided here and you will be fine.98Chapter 5. Python开开开发发发环环环境境境CHAPTER6附附附加加加说说说明明明本章内容比较单调,先介绍一些关于Python的背景,然后聚焦于接下来的内容。IntroductionFrom the official Python webs

458、ite:Python is a general-purpose, high-level programming language similar to Tcl, Perl, Ruby, Scheme, or Java. Some ofits main key features include: very clear, readable syntaxPythons philosophy focuses on readability, from code blocks delineated with significant whitespace to intuitivekeywords in pl

459、ace of inscrutable punctuation. extensive standard libraries and third party modules for virtually any taskPython is sometimes described with the words “batteries included” because of its extensive standard library,which includes modules for regular expressions, file IO, fraction handling, object se

460、rialization, and much more.Additionally, the Python Package Index is available for users to submit their packages for widespread use,similar to Perls CPAN. There is a thriving community of very powerful Python frameworks and tools like theDjango web framework and the NumPy set of math routines. inte

461、gration with other systemsPython can integrate with Java libraries, enabling it to be used with the rich Java environment that corporateprogrammers are used to. It can also be extended by C or C+ modules when speed is of the essence. ubiquity on computersPythonisavailableonWindows, *nix, andMac. Itr

462、unswherevertheJavavirtualmachineruns, andthereferenceimplementation CPython can help bring Python to wherever there is a working C compiler. friendly communityPython has a vibrant and large community which maintains wikis, conferences, countless repositories, mailinglists, IRC channels, and so much

463、more. Heck, the Python community is even helping to write this guide!About This Guide99Python Guide Documentation, 发发发布布布 0.0.1PurposeThe Hitchhikers Guide to Python exists to provide both novice and expert Python developers a best practice handbookfor the installation, configuration, and usage of P

464、ython on a daily basis.By the CommunityThis guide is architected and maintained by Kenneth Reitz in an open fashion. This is a community-driven effort thatserves one purpose: to serve the community.For the CommunityAll contributions to the Guide are welcome, from Pythonistas of all levels. If you th

465、ink theres a gap in what the Guidecovers, fork the Guide on GitHub and submit a pull request.Contributions are welcome from everyone, whether theyre an old hand or a first-time Pythonista, and the authorsto the Guide will gladly help if you have any questions about the appropriateness, completeness,

466、 or accuracy of acontribution.To get started working on The Hitchhikers Guide, see the Contribute page.The CommunityBDFLGuido van Rossum, the creator of Python, is often referred to as the BDFL the Benevolent Dictator For Life.Python Software FoundationThemissionofthePythonSoftwareFoundationistoprom

467、ote, protect, andadvancethePythonprogramminglanguage,and to support and facilitate the growth of a diverse and international community of Python programmers.Learn More about the PSF.PEPsPEPs are Python Enhancement Proposals. They describe changes to Python itself, or the standards around it.There ar

468、e three different types of PEPs (as defined by PEP 1):Standards Describes a new feature or implementation.Informational Describes a design issue, general guidelines, or information to the community.Process Describes a process related to Python.Notable PEPsThere are a few PEPs that could be considere

469、d required reading: PEP 8: The Python Style Guide. Read this. All of it. Follow it. PEP 20: The Zen of Python. A list of 19 statements that briefly explain the philosophy behind Python.100Chapter 6. 附附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1 PEP 257: Docstring Conventions. Gives guidelines

470、 for semantics and conventions associated with Pythondocstrings.You can read more at The PEP Index.Submitting a PEPPEPs are peer-reviewed and accepted/rejected after much discussion. Anyone can write and submit a PEP for review.Heres an overview of the PEP acceptance workflow:Python ConferencesThe m

471、ajor events for the Python community are developer conferences. The two most notable conferences are PyCon,which is held in the US, and its European sibling, EuroPython.A comprehensive list of conferences is maintained at pycon.org.Python User GroupsUser Groups are where a bunch of Python developers

472、 meet to present or talk about Python topics of interest. A list oflocal user groups is maintained at the Python Software Foundation Wiki.Learning PythonBeginnerThe Python TutorialThis is the official tutorial. It covers all the basics, and offers a tour of the language and the standard library. Rec

473、om-mended for those who need a quick-start guide to the language.The Python Tutorial6.3. Learning Python101Python Guide Documentation, 发发发布布布 0.0.1Python for B is a tutorial focuses on beginner programmers. It covers many python concepts in depth. It alsoteaches you some advance constructs of python

474、 like lambda expression, regular expression. At last it finishes off withtutorial “How to access MySQL db using python”Python for beginnersLearn Python Interactive TutorialLearnpython.org is an easy non-intimidating way to get introduced to Python. The website takes the same approachused on the popu

475、lar Try Ruby website, it has an interactive Python interpreter built into the site that allows you to gothrough the lessons without having to install Python locally.Learn PythonIf you want a more traditional book, Python For You and Me is an excellent resource for learning all aspects of thelanguage

476、.Python for You and MeOnline Python TutorOnline Python Tutor gives you a visual step by step representation of how your program runs. Python Tutor helpspeople overcome a fundamental barrier to learning programming by understanding what happens as the computerexecutes each line of a programs source c

477、ode.Online Python TutorInvent Your Own Computer Games with PythonThis beginners book is for those with no programming experience at all. Each chapter has the source code to asmall game, using these example programs to demonstrate programming concepts to give the reader an idea of whatprograms “look

478、like”.Invent Your Own Computer Games with PythonHacking Secret Ciphers with PythonThis book teaches Python programming and basic cryptography for absolute beginners. The chapters provide thesource code for various ciphers, as well as programs that can break them.Hacking Secret Ciphers with PythonLea

479、rn Python the Hard WayThis is an excellent beginner programmers guide to Python. It covers “hello world” from the console to the web.Learn Python the Hard Way102Chapter 6. 附附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1Crash into PythonAlso known as Python for Programmers with 3 Hours, this gui

480、de gives experienced developers from other languagesa crash course on Python.Crash into PythonDive Into Python 3Dive Into Python 3 is a good book for those ready to jump in to Python 3. Its a good read if you are moving fromPython 2 to 3 or if you already have some experience programming in another

481、language.Dive Into Python 3Think Python: How to Think Like a Computer ScientistThink Python attempts to give an introduction to basic concepts in computer science through the use of the Pythonlanguage. The focus was to create a book with plenty of exercises, minimal jargon and a section in each chap

482、terdevoted to the subject of debugging.While exploring the various features available in the Python language the author weaves in various design patterns andbest practices.The book also includes several case studies which have the reader explore the topics discussed in the book in greaterdetail by a

483、pplying those topics to real-world examples. Case studies include assignments in GUI and Markov Analysis.Think PythonPython KoansPython Koans is a port of Edgecases Ruby Koans. It uses a test-driven approach, q.v. TEST DRIVEN DESIGNSECTION to provide an interactive tutorial teaching basic Python con

484、cepts. By fixing assertion statements that fail ina test script, this provides sequential steps to learning Python.For those used to languages and figuring out puzzles on their own, this can be a fun, attractive option. For those newto Python and programming, having an additional resource or referen

485、ce will be helpful.Python KoansMore information about test driven development can be found at these resources:Test Driven DevelopmentA Byte of PythonA free introductory book that teaches Python at the beginner level, it assumes no previous programming experience.A Byte of Python for Python 2.x A Byt

486、e of Python for Python 3.xLearn to Program in Python with CodeacademyA Codeacademy course for the absolute Python beginner. This free and interactive course provides and teaches thebasics (and beyond) of Python programming whilst testing the users knowledge in between progress. This course alsofeatu

487、res a built-in interpreter for receiving instant feedback on your learning.Learn to Program in Python with Codeacademy6.3. Learning Python103Python Guide Documentation, 发发发布布布 0.0.1IntermediateEffective PythonThis book contains 59 specific ways to improve writing Pythonic code. At 227 pages, it is a

488、 very brief overviewof some of the most commons adapations programmers need to make to become efficient intermediate level Pythonprogrammers.Effective PythonAdvancedPro PythonThis book is for intermediate to advanced Python programmers who are looking to understand how and why Pythonworks the way it

489、 does and how they can take their code to the next level.Pro PythonExpert Python ProgrammingExpert Python Programming deals with best practices in programming Python and is focused on the more advancedcrowd.It starts with topics like decorators (with caching, proxy, and context manager case-studies)

490、, method resolution order,using super() and meta-programming, and general PEP 8 best practices.It has a detailed, multi-chapter case study on writing and releasing a package and eventually an application, includ-ing a chapter on using zc.buildout. Later chapters detail best practices such as writing

491、 documentation, test-drivendevelopment, version control, optimization and profiling.Expert Python ProgrammingA Guide to Pythons Magic MethodsThis is a collection of blog posts by Rafe Kettler which explain magic methods in Python. Magic methods aresurrounded by double underscores (i.e. _init_) and c

492、an make classes and objects behave in different and magicalways.A Guide to Pythons Magic Methods注注注解解解: The R is currently down, you can go to their Github version directly. Here you can find a PDFversion: A Guide to Pythons Magic Methods (repo on GitHub)For Engineers and ScientistsA Primer on Scien

493、tific Programming with PythonA Primer on Scientific Programming with Python, written by Hans Petter Langtangen, mainly covers Pythons usagein the scientific field. In the book, examples are chosen from mathematics and the natural sciences.A Primer on Scientific Programming with Python104Chapter 6. 附

494、附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1Numerical Methods in Engineering with PythonNumerical Methods in Engineering with Python, written by Jaan Kiusalaas, puts the emphasis on numerical methodsand how to implement them in Python.Numerical Methods in Engineering with PythonMiscellaneous

495、topicsProblem Solving with Algorithms and Data StructuresProblem Solving with Algorithms and Data Structures covers a range of data structures and algorithms. All conceptsare illustrated with Python code along with interactive samples that can be run directly in the browser.Problem Solving with Algo

496、rithms and Data StructuresProgramming Collective IntelligenceProgramming Collective Intelligence introduces a wide array of basic machine learning and data mining methods. Theexposition is not very mathematically formal, but rather focuses on explaining the underlying intuition and shows howto imple

497、ment the algorithms in Python.Programming Collective IntelligenceTransforming Code into Beautiful, Idiomatic PythonTransforming Code into Beautiful, Idiomatic Python is a video by Raymond Hettinger. Learn to take better advantageof Pythons best features and improve existing code through a series of

498、code transformations, “When you see this, dothat instead.”Transforming Code into Beautiful, Idiomatic PythonFullstack PythonFullstack Python offers a complete top-to-bottom resource for web development using Python.From setting up the webserver, to designing the front-end, choosing a database, optim

499、izing/scaling, etc.As the name suggests, it covers everything you need to build and run a complete web app from scratch.Fullstack PythonReferencesPython in a NutshellPython in a Nutshell, written by Alex Martelli, covers most cross-platform Pythons usage, from its syntax to built-inlibraries to adva

500、nced topics such as writing C extensions.Python in a Nutshell6.3. Learning Python105Python Guide Documentation, 发发发布布布 0.0.1The Python Language ReferenceThis is Pythons reference manual, it covers the syntax and the core semantics of the language.The Python Language ReferencePython Essential Referen

501、cePython Essential Reference, written by David Beazley, is the definitive reference guide to Python. It concisely explainsboth the core language and the most essential parts of the standard library. It covers Python 3 and 2.6 versions.Python Essential ReferencePython Pocket ReferencePython Pocket Re

502、ference, written by Mark Lutz, is an easy to use reference to the core language, with descriptions ofcommonly used modules and toolkits. It covers Python 3 and 2.6 versions.Python Pocket ReferencePython CookbookPython Cookbook, written by David Beazley and Brian K. Jones, is packed with practical re

503、cipes. This book coversthe core python language as well as tasks common to a wide variety of application domains.Python CookbookWriting Idiomatic Python“Writing Idiomatic Python”, written by Jeff Knupp, contains the most common and important Python idioms in aformat that maximizes identification and

504、 understanding. Each idiom is presented as a recommendation of a way towrite some commonly used piece of code, followed by an explanation of why the idiom is important. It also containstwo code samples for each idiom: the “Harmful” way to write it and the “Idiomatic” way.For Python 2.7.3+For Python

505、3.3+DocumentationOfficial DocumentationThe official Python Language and Library documentation can be found here: Python 2.x Python 3.x106Chapter 6. 附附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1Read the DocsRead the Docs is a popular community project that hosts documentation for open source s

506、oftware. It holds documen-tation for many Python modules, both popular and exotic.Read the Docspydocpydoc is a utility that is installed when you install Python. It allows you to quickly retrieve and search for documen-tation from your shell. For example, if you needed a quick refresher on the time

507、module, pulling up documentationwould be as simple as$ pydoc timeThe above command is essentially equivalent to opening the Python REPL and running help(time)NewsPlanet PythonThis is an aggregate of Python news from a growing number of developers.Planet Python/r/python/r/python is the Reddit Python

508、community where users contribute and vote on Python-related news./r/pythonPycoders WeeklyPycoders Weekly is a free weekly Python newsletter for Python developers by Python developers (Projects, Articles,News, and Jobs).Pycoders WeeklyPython WeeklyPython Weekly is a free weekly newsletter featuring c

509、urated news, articles, new releases, jobs, etc. related to Python.Python WeeklyPython NewsPython News is the news section in the official Python web site (www.python.org). It briefly highlights the news fromthe Python community.Python News6.5. News107Python Guide Documentation, 发发发布布布 0.0.1Import Py

510、thon WeeklyWeekly Python Newsletter containing Python Articles, Projects, Videos, Tweets delivered in your inbox. Keep YourPython Programming Skills Updated.Import Python Weekly NewsletterAwesome Python NewsletterA weekly overview of the most popular Python news, articles and packages.Awesome Python

511、 Newsletter注注注解解解:所有的全音阶和半音音阶中定义的注意事项已经有意从附加说明这个名单中排除。除了此说明。(说实话,我也不太明白什么意思,字面翻译-_-|)贡献说明以及法律信息(给那些感兴趣的人)。ContributePython-guide is under active development, and contributors are welcome.If you have a feature request, suggestion, or bug report, please open a new issue on GitHub. To submit patches,pl

512、ease send a pull request on GitHub. Once your changes get merged back in, youll automatically be added to theContributors List.Style GuideFor all contributions, please follow the The Guide Style Guide.Todo ListIf youd like to contribute, theres plenty to do. Heres a short todo list. 创建 “使用这个” vs “可选

513、的是.” 的推荐介绍待待待处处处理理理Write about Blueprint(原始记录见/home/docs/checkouts/readthedocs.org/user_builds/pyguide/checkouts/latest/docs/scenarios/admin.rst,第 369 行)待待待处处处理理理Fill in “Freezing Your Code” stub108Chapter 6. 附附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1(原始记录见/home/docs/checkouts/readthedocs.

514、org/user_builds/pyguide/checkouts/latest/docs/shipping/freezing.rst,第 37 行)待待待处处处理理理Write steps for most basic .exe(原始记录见/home/docs/checkouts/readthedocs.org/user_builds/pyguide/checkouts/latest/docs/shipping/freezing.rst,第 73 行)待待待处处处理理理增加上述每个项目里代码的典型示例。解释为什么这是优秀的代码。可以使用一些较为复杂的示例。(原始记录见/home/docs/c

515、heckouts/readthedocs.org/user_builds/pyguide/checkouts/latest/docs/writing/reading.rst,第 35 行)待待待处处处理理理讲述一些可以快速确定数据结构、算法并确定代码实现什么功能的技术。(原始记录见/home/docs/checkouts/readthedocs.org/user_builds/pyguide/checkouts/latest/docs/writing/reading.rst,第 37 行)LicenseThe Guide is licensed under the Creative Commo

516、ns Attribution-NonCommercial-ShareAlike 3.0 Unported license.The Guide Style GuideAs with all documentation, having a consistent format helps make the document more understandable. In order tomake The Guide easier to digest, all contributions should fit within the rules of this style guide where app

517、ropriate.The Guide is written as reStructuredText.注注注解解解: Parts of The Guide may not yet match this style guide. Feel free to update those parts to be in sync with TheGuide Style Guide注注注解解解: On any page of the rendered HTML you can click “Show Source” to see how authors have styled the page.Relevan

518、cyStrive to keep any contributions relevant to the purpose of The Guide. Avoid including too much information on subjects that dont directly relate to Python development.6.7. License109Python Guide Documentation, 发发发布布布 0.0.1 Prefer to link to other sources if the information is already out there. B

519、e sure to describe what and why you arelinking. Cite references where needed. Ifa subjectisntdirectly relevanttoPython, butusefulin conjunction withPython(e.g., Git, GitHub, Databases),reference by linking to useful resources, and describe why its useful to Python. When in doubt, ask.HeadingsUse the

520、 following styles for headings.Chapter title:#Chapter 1#Page title:=Time is an Illusion=Section headings:Lunchtime Doubly So-Sub section headings:Very DeepProseWrap text lines at 78 characters. Where necessary, lines may exceed 78 characters, especially if wrapping would makethe source text more dif

521、ficult to read.Use of the serial comma (also known as the Oxford comma) is 100% non-optional. Any attempt to submit contentwith a missing serial comma will result in permanent banishment from this project, due to complete and total lack oftaste.Banishment? Is this a joke? Hopefully we will never hav

522、e to find out.Code ExamplesWrap all code examples at 70 characters to avoid horizontal scrollbars.Command line examples:. code-block: console$ run command -help$ ls .110Chapter 6. 附附附加加加说说说明明明Python Guide Documentation, 发发发布布布 0.0.1Be sure to include the $ prefix before each line.Python interpreter

523、examples:Label the example:. code-block: python import thisPython examples:Descriptive title:. code-block: pythondef get_answer():return 42Externally Linking Prefer labels for well known subjects (ex: proper nouns) when linking:Sphinx_ is used to document Python. _Sphinx: http:/sphinx.pocoo.org Pref

524、er to use descriptive labels with inline links instead of leaving bare links:Read the Sphinx Tutorial _ Avoid using labels such as “click here”, “this”, etc. preferring descriptive labels (SEO worthy) instead.Linking to Sections in The GuideTo cross-reference other parts of this documentation, use t

525、he :ref: keyword and labels.To make reference labels more clear and unique, always add a -ref suffix:. _some-section-ref:Some Section-Notes and WarningsMake use of the appropriate admonitions directives when making notes.Notes:. note:The Hitchhikers Guide to the Galaxy has a few things to sayon the

526、subject of towels. A towel, it says, is about the mostmassively useful thing an interstellar hitch hiker can have.Warnings:6.8. The Guide Style Guide111Python Guide Documentation, 发发发布布布 0.0.1. warning: DONT PANICTODOsPlease mark any incomplete areas of The Guide with a todo directive. To avoid clut

527、tering the Todo List, use a singletodo for stub documents or large incomplete sections. todo:Learn the Ultimate Answer to the Ultimate Questionof Life, The Universe, and Everything112Chapter 6. 附附附加加加说说说明明明索引PPATH, 6, 7Python 提高建议PEP 0257#specification, 32PEP 1, 100PEP 20, 26, 100PEP 249, 56PEP 257, 34, 101PEP 282, 38PEP 3101, 21PEP 3132, 25PEP 3333, 46PEP 391, 40PEP 8, 27, 89, 100, 104PEP 8#comments, 32环境变量PATH, 6, 7113

展开阅读全文
相关资源
相关搜索

当前位置:首页 > 办公文档 > 解决方案

电脑版 |金锄头文库版权所有
经营许可证:蜀ICP备13022795号 | 川公网安备 51140202000112号