├── Makefile ├── images └── vim-pyflakes.png └── pyeco.rst /Makefile: -------------------------------------------------------------------------------- 1 | 2 | pyeco.html : pyeco.rst 3 | rst2html pyeco.rst pyeco.html 4 | 5 | .PHONY : clean 6 | clean : 7 | -rm pyeco.html 8 | -------------------------------------------------------------------------------- /images/vim-pyflakes.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/dongchao-1/pyeco/93d4121437a53766314835d53e5179b21c5b23a8/images/vim-pyflakes.png -------------------------------------------------------------------------------- /pyeco.rst: -------------------------------------------------------------------------------- 1 | ====================== 2 | Python开发生态环境简介 3 | ====================== 4 | 5 | :作者: `Mir Nazim`_ 6 | :原文: `Python Ecosystem - An Introduction`_ 7 | :译者: `dccrazyboy`_ 8 | 9 | .. _`Mir Nazim`: http://mirnazim.org/about/ 10 | .. _`Python Ecosystem - An Introduction`: http://mirnazim.org/writings/python-ecosystem-introduction/ 11 | .. _`dccrazyboy`: dccrazyboy@gmail.com 12 | 13 | 14 | 当开发人员从PHP,Ruby或者别的开发环境转换到Python时,所面对的最大问题是缺乏对Python开发的生态环境的充分理解。开发人员非常想得到一份关于完成大多数任务的指南或资源,而不论使用的方法是否规范。 15 | 16 | 下文所讲到的基本上都来源于我的\ 网站_\ ,那存储着Python环境下对于网络应用开发的一些基本资料,这些资料是为那些从别的平台转到Python开发的实习生,研究生和有经验的开发者准备的。 17 | 18 | .. _网站 : http://ikraftsoft.com/ 19 | 20 | 这不是一个完美的文档,我的目标是将它做成一个\ **永久的文档**\ ,但愿这篇文档可以发展成为一个详细的教程。 21 | 22 | 23 | 目标读者 24 | ======== 25 | 26 | 这不是一本关于Python的语法书。 27 | 这个教程不会教你花哨的Python用法让你成为一名Python黑客。 28 | 我默认你已经了解Python的基础用法。如果你不知道,别往下看了。 29 | 先去看看Zed Shaw的免费教Python入门的书\ `《Learn Python The Hard Way》`_\ 。 30 | 31 | .. _《Learn Python The Hard Way》: http://learnpythonthehardway.org/ 32 | 33 | 我不知道你是不是在用Linux(最好是Ubuntu/Debian)或者是类Linux系统。 34 | 为毛?因为Linux是我最了解的系统。 35 | 除了测试跨浏览器兼容性以外,我从没在Windows或者Max OS X上面开发过。 36 | 下面是如何在不同平台安装Python的教程。 37 | 38 | - `Python 101: Setting up Python on Windows`_ 39 | - `Official documentation for Python on Windows`_ 40 | - `Official documentation for Python on Mac OS X`_ 41 | 42 | .. _`Python 101: Setting up Python on Windows`: http://www.blog.pythonlibrary.org/2011/11/24/python-101-setting-up-python-on-windows/ 43 | 44 | .. _`Official documentation for Python on Windows`: http://docs.python.org/using/windows.html 45 | 46 | .. _`Official documentation for Python on Mac OS X`: http://docs.python.org/using/mac.html 47 | 48 | 去搜索下最适合你平台的Python安装方法。我强烈建议问Stack Overflow。 49 | 50 | 51 | 版本之惑 52 | ======== 53 | 54 | Python 2.x是一个稳定的版本,Python 3是个新的版本。如果你不在乎,跳过这段直接看下面的Python安装部分。 55 | 56 | 当开始学习Python时,安个3.x的版本看上去应该是第一步,但它可能并不一定是你想要的。 57 | 58 | 现在Python有两个正在开发的版本-2.7.x和3.x(也被称为Python3,Py3k或Python 3000)。 59 | 跟Python2相比Python3就是另外一个语言。它们之间存在者或大或小的语法差异。 60 | 现今Python2.6/2.7是被安装和应用的最为广泛的版本。 61 | 许多的主流代码和一些重要的packages/frameworks/tools/utilities/modules并不支持Python3。 62 | 63 | 因此,最安全的选择是使用2.x(2.7最好)版本。如果你完全了解Python3的话在再用它。 64 | 65 | `Python 3 Wall of Shame`_ 列出了很多包在Python3中的兼容性。在决定用Python3之前好好看看这个。 66 | 67 | 68 | .. _`Python 3 Wall of Shame`: http://python3wos.appspot.com/ 69 | 70 | 71 | 72 | VM挑选 73 | ====== 74 | 75 | Python解释器或Python虚拟机有很多种实现,CPython是最主流的实现。CPython同时也是别的虚拟机实现的参考解释器。 76 | 77 | PyPy是用Python实现的Python解释器,Jython是用Java实现运行在JVM上的解释器,IronPython是用Microsoft .NET CLR实现的解释器。 78 | 79 | 除非解释器的选择非常非常重要,我们一般都用CPython。 80 | 81 | 如果上面那些关于版本和虚拟机的废话让你头疼,那你就安装CPython的2.7.x版本,相信我! 82 | 83 | 安装Python 84 | ========== 85 | 86 | 大多数的Linux/Unix系统的Max OS X都自带Python。如果没有或者版本过低,你可以通过下面的命令安装: 87 | 88 | Ubuntu/Debian及其衍生系统:: 89 | 90 | $ sudo apt-get install python2.7 91 | 92 | ``sudo`` 是一个是类Unix系统的一个命令,它允许用户以别的用户(一般是超级用户,或者root)的权限运行程序。 `更多请查阅Wikipedia`_ 。 93 | 94 | .. _`更多请查阅Wikipedia`: http://en.wikipedia.org/wiki/Sudo 95 | 96 | Fedora/Red Hat及类似系统:: 97 | 98 | sudo yum install python2.7 99 | 100 | 使用RHEL你可能需要打开EPEL Repositories才能安装。 101 | 102 | 从这起,我将在例子中使用sudo,你需要根据你的系统进行更改。 103 | 104 | 理解包 105 | ====== 106 | 107 | 你首先需要理解的是Python没有一个默认的包管理设施。事实上,包的概念在Python中是相当弱的。 108 | 109 | 可能你已经知道,Python代码被组织为模块。 110 | 一个模块可能由包含一个函数的单一文件组成,也可能由包含多个模块的目录组成。 111 | 包和模块的区别非常小,并且每个模块都能被理解为包。 112 | 113 | 那么包和模块的区别到底是什么(如果有的话)?为了明白这个,你首先应该明白Python是如何查找模块的。 114 | 115 | 如同别的编程环境一样,Python中的一些函数和类(例如str,len,Exception等)在全局(叫做内置函数)都是可用的。 116 | 别的就需要通过手动 ``import`` 进来。例如:: 117 | 118 | >>> import os 119 | >>> from os.path import basename, dirname 120 | 121 | 这个包一定存在你的机子上,这样才能被import语句导入。但Python是如何知道这些模块的位置呢? 122 | 这些位置信息在你安装Python虚拟机时就被自动设置好了,并且依赖于你的目标平台。 123 | 124 | 包的路径可以在sys.path中查询。下面是在我的笔记本上的结果,运行环境是Ubuntu 11.10。 :: 125 | 126 | >>> import sys 127 | 128 | >>> print sys.path 129 | 130 | ['', 131 | 132 | '/usr/lib/python2.7', 133 | 134 | '/usr/lib/python2.7/plat-linux2', 135 | 136 | '/usr/lib/python2.7/lib-tk', 137 | 138 | '/usr/lib/python2.7/lib-old', 139 | 140 | '/usr/lib/python2.7/lib-dynload', 141 | 142 | '/usr/local/lib/python2.7/dist-packages', 143 | 144 | '/usr/lib/python2.7/dist-packages', 145 | 146 | '/usr/lib/python2.7/dist-packages/PIL', 147 | 148 | '/usr/lib/python2.7/dist-packages/gst-0.10', 149 | 150 | '/usr/lib/python2.7/dist-packages/gtk-2.0', 151 | 152 | '/usr/lib/pymodules/python2.7', 153 | 154 | '/usr/lib/python2.7/dist-packages/ubuntu-sso-client', 155 | 156 | '/usr/lib/python2.7/dist-packages/ubuntuone-client', 157 | 158 | '/usr/lib/python2.7/dist-packages/ubuntuone-control-panel', 159 | 160 | '/usr/lib/python2.7/dist-packages/ubuntuone-couch', 161 | 162 | '/usr/lib/python2.7/dist-packages/ubuntuone-installer', 163 | 164 | '/usr/lib/python2.7/dist-packages/ubuntuone-storage-protocol'] 165 | 166 | 这里给出了Python搜索包的路径。它将从最上面开始找,直到找到一个名字相符的。 167 | 这表明如果两个不同的路径分别包含了两个具有相同名字的包,搜索将在找到第一个名字的时候停止,然后将永远不会往下查找。 168 | 169 | 正如你所猜的,包搜索路径很容易被劫持,为了确保Python首先载入你的包,所需做的如下: :: 170 | 171 | >>> sys.path.insert(0, '/path/to/my/packages') 172 | 173 | 尽管这个方法在很多情况下都很好用,但一定要小心不要滥用。 **只有当必要时再使用!不要滥用!** 174 | 175 | ``site`` 模块控制包的搜索路径。当Python虚拟机初始化时它会自动被导入。如果你想了解更多信息,请看 `官方文档`_ 。 176 | 177 | .. _`官方文档`: http://docs.python.org/library/site.html 178 | 179 | PYTHONPATH变量 180 | -------------- 181 | 182 | ``PYTHONPATH`` 是一个用来增加默认包搜索目录的环境变量。可以认为它是对于Python的一个特殊的 ``PATH`` 变量。 183 | 它仅仅是一个通过 ``:`` 分割,包含Python模块目录的列表(并不是类似于 ``sys.path`` 的Python list)。 184 | 它可能就类似下面这样: :: 185 | 186 | export PYTHONPATH=/path/to/some/directory:/path/to/another/directory:/path/to/yet/another/directory 187 | 188 | 有时候你可能并不想覆盖掉现存的 ``PYTHONPATH`` ,而仅仅是希望添加新目录到头部或尾部。 :: 189 | 190 | export PYTHONPATH=$PYTHONPATH:/path/to/some/directory # Append 191 | export PYTHONPATH=/path/to/some/directory:$PYTHONPATH # Prepend 192 | 193 | ``PYTHONPATH`` , ``sys.path.insert`` 这些方法并非完美,我们最好也不要用这些方法。 194 | 使用它们,你可能可以解决本地的开发环境问题,但它在别的环境下也许并不适用。 195 | 有很多种方法可以达到这个效果,在下面我将一一阐述。 196 | 197 | 我们现在明白的Python如何找到安装的包路径,现在让我们回到开始那个问题。 198 | 模块和包的区别到底是什么?包是一个模块或模块/子模块的集合,一般情况下被压缩到一个压缩包中。 199 | 其中包含1)依赖信息 2)将文件拷贝到标准的包搜索路径的指令。3)编译指令(如果在安装前代码必须被编译的话)。 200 | 就这些东西! 201 | 202 | 第三方包 203 | ======== 204 | 205 | 206 | 从一开始,如果要做一些实际Python开发,你一定会用到一些第三方包。 207 | 208 | 在Linux系统上至少有3种安装第三方包的方法。 209 | 210 | 1. 使用系统自带的包管理系统(deb, rpm, 等) 211 | 2. 通过社区开发的各种工具,例如 ``pip`` , ``easy_install`` 等 212 | 3. 从源文件安装 213 | 214 | 这三个方面,几乎完成同样的事情。即:安装依赖,编译代码(如果需要的话),将一个包含模块的包复制的标准软件包搜索位置。 215 | 216 | 第二步和第三步在所有的操作系统上基本相同。 217 | 我再次希望您可以在 `Stack Overflow`_ 上找到你的平台的第三方包安装方法。 218 | 219 | .. _`Stack OverFlow`: http://www.stackoverflow.com/ 220 | 221 | 222 | 在哪找第三方包? 223 | ---------------- 224 | 225 | 在安装第三方包之前,你首先要找到他们。以下是几种方法: 226 | 227 | 1. 你的系统包管理器中的发行版专用包。 228 | 2. `Python Package Index (or PyPI)`_ 229 | 3. 大量的源代码服务器,例如 `Launchpad`_, `GitHub`_, `BitBucket`_ 等 230 | 231 | .. _`Python Package Index (or PyPI)`: http://pypi.python.org/pypi 232 | .. _`Launchpad`: https://launchpad.net/ 233 | .. _`GitHub`: http://github.com/ 234 | .. _`BitBucket`: https://bitbucket.org/ 235 | 236 | 237 | 通过发行版专用包安装 238 | -------------------- 239 | 240 | 通过包管理器安装包安装包就像使用命令行或者GUI安装别的软件那样简单。 241 | 例如在Ubuntu中安装 ``simplejson`` :: 242 | 243 | $ sudo apt-get install python-simplejson 244 | 245 | 通过pip安装 246 | ----------- 247 | 248 | easy_install渐渐不再流行。我们将主要介绍pip,它是easy_install的一个替代品。 249 | 250 | pip是一个用来安装和管理Python包的工具,就如同Python Packet Index一样。 251 | pip并没有随着Python一起安装,因此我们需要先安装它。Linux下,一般这样安装: 252 | 253 | :: 254 | 255 | $ sudo apt-get install python-pip 256 | 257 | 在安装任何其他包之前,我总是通过PyPI将pip升级到最新版本的, 258 | Ubuntu软件库中的版本普遍落后的PyPI。我通过pip升级pip它自己。 259 | 260 | :: 261 | 262 | $ sudo pip install pip --upgrade 263 | 264 | 现在如果需要安装任何包,你可以运行 ``pip install package-name`` 命令。 265 | 所以可以通过下面命令安装 ``simplejson``: :: 266 | 267 | $ sudo pip install simplejson 268 | 269 | 删除包也很简单。 :: 270 | 271 | $ sudo pip uninstall simplejson 272 | 273 | 一般情况下, ``pip`` 会从PyPI自动安装最新的稳定版, 274 | 但有时我们需要安装一个特定版本的包,因为你的项目可能基于特殊的版本。 275 | 因此你可能需要使用类似如下的 ``pip install`` 命令: 276 | 277 | :: 278 | 279 | $ sudo pip install simplejson==2.2.1 280 | 281 | 我们可能需要升级/降级/重新安装包。此时可以通过下面的命令完成: 282 | 283 | :: 284 | 285 | $ sudo pip install simplejson --upgrade # Upgrade a package to the latest version from PyPI 286 | $ sudo pip install simplejson==2.2.1 --upgrade # Upgrade/downgrade a package to a given version 287 | 288 | 289 | 现在,如果你想安装一个处于开发版本的包,它在版本控制仓库有,但是PyPI中还没有怎么办? 290 | ``pip`` 能够很好的处理这种情况,但在这之前,你需要自己安装这个版本控制仓库。Ubuntu下,你可以如下安装: 291 | 292 | :: 293 | 294 | $ sudo apt-get install git-core mercurial subversion 295 | 296 | 安装版本控制仓库之后,从版本控制仓库安装包就如下所示: 297 | 298 | :: 299 | 300 | $ sudo pip install git+http://hostname_or_ip/path/to/git-repo#egg=packagename 301 | $ sudo pip install hg+http://hostname_or_ip/path/to/hg-repo#egg=packagename 302 | $ sudo pip install svn+http://hostname_or_ip/path/to/svn-repo#egg=packagename 303 | 304 | 你也可以同样简单的从本地仓库安装,注意下面的三斜杠是文件目录。 305 | 306 | :: 307 | 308 | $ sudo pip install git+file:///path/to/local/repository 309 | 310 | 有一点需要注意,如果使用 ``git`` 协议安装,你需要使用 ``git+git`` 前缀: 311 | 312 | :: 313 | 314 | $ sudo pip install git+git://hostname_or_ip/path/to/git-repo#egg=packagename 315 | 316 | 现在你可能会好奇这些 *egg* 会被怎么使用。 317 | 现在你需要明白的是一个egg是一个被压缩的Python包,里面包含了源代码和一些元数据。 318 | ``pip`` 在安装包前建立了egg信息。你可以在代码仓库的 ``setup.py`` 文件中找到egg名字。 319 | 找到 ``setup`` 块然后找到类似于 ``name="something"`` 的字段。 320 | 它可能看起来就像如下的代码(这段代码从simplejson的 ``srtup.py`` 得到)一样。 321 | 322 | :: 323 | 324 | setup( 325 | 326 | name="simplejson", # <--- This is your egg name 327 | 328 | version=VERSION, 329 | 330 | description=DESCRIPTION, 331 | 332 | long_description=LONG_DESCRIPTION, 333 | 334 | classifiers=CLASSIFIERS, 335 | 336 | author="Bob Ippolito", 337 | 338 | author_email="bob@redivi.com", 339 | 340 | url="http://github.com/simplejson/simplejson", 341 | 342 | license="MIT License", 343 | 344 | packages=['simplejson', 'simplejson.tests'], 345 | 346 | platforms=['any'], 347 | 348 | **kw) 349 | 350 | 351 | 如果没有 ``setup.py`` 文件咋办?这样如何找到egg名?其实我们不需要。 352 | 把包源码拷贝到你的工程目录下,然后导入进去就可以直接用了。 353 | 354 | --user 选项 355 | ----------- 356 | 357 | 上面的所有例子把包都安装到系统范围。如果你在 ``pip install`` 时使用 ``--user`` 选项,包将被安装到 ``~/.local`` 目录下。在我的机子上,如下所示: 358 | 359 | :: 360 | 361 | $ pip install --user markdown2 362 | 363 | Downloading/unpacking markdown2 364 | 365 | Downloading markdown2-1.0.1.19.zip (130Kb): 130Kb downloaded 366 | 367 | Running setup.py egg_info for package markdown2 368 | 369 | 370 | 371 | Installing collected packages: markdown2 372 | 373 | Running setup.py install for markdown2 374 | 375 | warning: build_py: byte-compiling is disabled, skipping. 376 | 377 | 378 | 379 | changing mode of build/scripts-2.7/markdown2 from 664 to 775 380 | 381 | warning: install_lib: byte-compiling is disabled, skipping. 382 | 383 | 384 | 385 | 386 | 387 | changing mode of /home/mir/.local/bin/markdown2 to 775 388 | 389 | Successfully installed markdown2 390 | 391 | Cleaning up... 392 | 393 | 注意: *markdown2* 被安装到 ``/home/mir/.local/bin/markdown2`` 这个目录下。 394 | 395 | 有很多原因使你不想将包安装到系统目录中。 396 | 稍后我将讲解如何对于每个项目设置独立的Python环境。 397 | 398 | 从源码安装 399 | ---------- 400 | 401 | 从源码安装包仅仅需要一个命令,解压这个包到一个目录,然后执行下面的命令。 402 | 403 | :: 404 | 405 | cd /path/to/package/directory 406 | 407 | python setup.py install 408 | 409 | 尽管这些安装的办法并没有什么不同,但 ``pip`` 方式是最好的。 410 | ``pip`` 让你拥有轻松升级/降级包的能力,而手动安装你就不得不去手动下载,解压的安装。 411 | 手动安装包应该使你最后一个选择,如果别的全部失败了(一般不太可能)。 412 | 413 | 安装需要编译的包 414 | ---------------- 415 | 416 | 我们现在已经了解了大多数包的安装方法,但有些包还没有介绍:包含C/C++代码的Python包,它们需要在安装前被编译。 417 | 关于这些包最好的例子是数据库适配器,图片处理库等。 418 | 419 | 虽然 ``pip`` 可以处理编译安装的源码,但我个人更喜欢使用发行版的包管理器提供的包。 420 | 它将会安装编译好的二进制文件。 421 | 422 | 如果你还是想用 ``pip`` 安装,下面是在Ubuntu系统上需要做的。 423 | 424 | 编译器的相关工具: 425 | 426 | :: 427 | 428 | $ sudo apt-get install build-essential 429 | 430 | Python开发环境(头文件等): 431 | 432 | :: 433 | 434 | $ sudo aptitude install python-dev-all 435 | 436 | 如果你的系统没有 ``python-dev-all`` ,看看这些相似的名字 ``python-dev`` , ``python2.X-dev`` 等等。 437 | 438 | 确保你已经安装了 ``psycopg2`` (PostgreSQL RDBMS adapter for Python),你将需要PostgreSQL的开发文件。 439 | 440 | :: 441 | 442 | $ sudo aptitude install postgresql-server-dev-all 443 | 444 | 完成这些依赖的安装后,你就能运行 ``pip install`` 了。 445 | 446 | :: 447 | 448 | $ sudo pip install psycopg2 449 | 450 | 还需要注意一点: **并不是所有的包都能通过pip编译安装!** 。 451 | 但如果你对编译安装很有自信,或者已经对于如何在自己的目标平台安装有足够的经验。 452 | 那就大胆的手动安装吧! 453 | 454 | 455 | Python开发环境 456 | ============== 457 | 458 | 不同的人喜欢用不同的方式建立各自的开发环境,但在几乎所有的编程社区,总有一个(或一个以上)开发环境让人更容易接受。 459 | 使用不同的开发环境虽然没有什么错误,但有些环境设置更容易进行便利的测试,并做一些重复/模板化的任务,使得在每天的日常工作简单并易于维护。 460 | 461 | virtualenv 462 | ---------- 463 | 464 | 在Python的开发环境的最常用的方法是使用virtualenv包。 465 | Virtualenv是一个用来创建独立的Python环境的包。现在,出现了这样的问题:为什么我们需要一个独立的Python环境? 466 | 要回答这个问题,请允许我引用virtualenv自己的文档: 467 | 468 | 我们需要处理的基本问题是包的依赖、版本和间接权限问题。想象一下,你有两个应用,一个应用需要libfoo的版本1,而另一应用需要版本2。如何才能同时使用这些应用程序?如果您安装到的/usr/lib/python2.7/site-packages(或任何平台的标准位置)的一切,在这种情况下,您可能会不小心升级不应该升级的应用程序。 469 | 470 | 简单地说,你可以为每个项目建立不同的/独立的Python环境,你将为每个项目安装所有需要的软件包到它们各自独立的环境中。 471 | 472 | 使用 ``pip`` 命令来安装virtualenv: 473 | 474 | :: 475 | 476 | $ sudo pip install virtualenv 477 | 478 | virtualenv安装完毕后,可以通过运行下面的命令来为你的项目创建独立的python环境。 479 | 480 | :: 481 | 482 | $ mkdir my_project_venv 483 | 484 | $ virtualenv --distribute my_project_venv 485 | 486 | # The output will something like: 487 | 488 | New python executable in my_project_venv/bin/python 489 | 490 | Installing distribute.............................................done. 491 | 492 | Installing pip.....................done. 493 | 494 | 495 | 上面发生了什么?你创建了文件夹 ``my_project_venv`` 来存储你的新的独立Python环境。 496 | ``--distribute`` 选项使virtualenv使用新的基于发行版的包管理系统而不是 ``setuptools`` 获得的包。 497 | 你现在需要知道的就是 ``--distribute`` 选项会自动在新的虚拟环境中安装 ``pip`` ,这样就不需要手动安装了。 498 | 当你成为一个更有经验的Python开发者,你就会明白其中细节。 499 | 500 | 现在看看 ``my_project_venv`` 目录,你会看到这样的结构: 501 | 502 | :: 503 | 504 | # 这里只列出了将被讨论的目录和文件 505 | 506 | . 507 | 508 | |-- bin 509 | 510 | | |-- activate # <-- 这个virtualenv的激活文件 511 | 512 | | |-- pip # <-- 这个virtualenv的独立pip 513 | 514 | | `-- python # <-- python解释器的一个副本 515 | 516 | `-- lib 517 | 518 | `-- python2.7 # <-- 所有的新包会被存在这 519 | 520 | 521 | 通过下面的命令激活这个virtualenv: 522 | 523 | :: 524 | 525 | $ cd my_project_venv 526 | 527 | $ source bin/activate 528 | 529 | 执行完毕后,提示可能是这个样子的: 530 | 531 | :: 532 | 533 | (my_project_venv)$ # the virtualenv name prepended to the prompt 534 | 535 | 通过 deactivate 命令离开virtualenv环境 536 | 537 | :: 538 | 539 | (my_project_venv)$ deactivate 540 | 541 | 运行下面的命令可以更好地理解两者的差异,如果已经进入virtualenv请先离开。 542 | 543 | 首先让我们看看如果调用python/pip命令它会调用那一个。 544 | 545 | :: 546 | 547 | $ which python 548 | 549 | /usr/bin/python 550 | 551 | $ which pip 552 | 553 | /usr/local/bin/pip 554 | 555 | 再来一次!这次打开virtualenv,然后看看有什么不同。我的机子上显示如下: 556 | 557 | :: 558 | 559 | $ cd my_project_venv 560 | 561 | $ source bin/activate 562 | 563 | (my_project_venv)$ which python 564 | 565 | /home/mir/my_project_venv/bin/python 566 | 567 | (my_project_venv)$ which pip 568 | 569 | /home/mir/my_project_venv/bin/pip 570 | 571 | virtualenv拷贝了Python可执行文件的副本,并创建一些有用的脚本和安装了项目需要的软件包,你可以在项目的整个生命周期中安装/升级/删除这些包。 572 | 它也修改了一些搜索路径,例如PYTHONPATH,以确保: 573 | 574 | 1) 当安装包时,它们被安装在当前活动的virtualenv里,而不是系统范围内的Python路径 575 | 2) 当import代码时,virtualenv将优先采取本环境中安装的包,而不是系统Python目录中安装的包。 576 | 577 | 578 | 还有一点比较重要,在默认情况下,所有安装在系统范围内的包对于virtualenv是可见的。 579 | 这意味着如果你将simplejson安装在您的系统Python目录中,它会自动提供给所有的virtualenvs使用。 580 | 这种行为可以被更改,在创建virtualenv时增加 ``--no-site-packages`` 选项的virtualenv就不会读取系统包,如下: 581 | 582 | :: 583 | 584 | $ virtualenv my_project_venv --no-site-packages 585 | 586 | virtualenvwrapper 587 | ----------------- 588 | 589 | ``virtualenvwrapper`` 是一个建立在 ``virtualenv`` 上的工具,通过它可以方便的创建/激活/管理/销毁虚拟环境,没它的话进行上面的操作将会相当麻烦。 590 | 可以通过下面命令安装 ``virtualenvwrapper`` 。 591 | 592 | :: 593 | 594 | $ sudo pip install virtualenvwrapper 595 | 596 | 安装后,你需要配置它。下面是我的配置: 597 | 598 | :: 599 | 600 | if [ `id -u` != '0' ]; then 601 | 602 | export VIRTUALENV_USE_DISTRIBUTE=1 # <-- Always use pip/distribute 603 | 604 | export WORKON_HOME=$HOME/.virtualenvs # <-- Where all virtualenvs will be stored 605 | 606 | source /usr/local/bin/virtualenvwrapper.sh 607 | 608 | export PIP_VIRTUALENV_BASE=$WORKON_HOME 609 | 610 | export PIP_RESPECT_VIRTUALENV=true 611 | 612 | fi 613 | 614 | 设置 ``WORKON_HOME`` 和 ``source /usr/local/bin/virtualenvwrapper.sh`` 只需要几行代码,别的部分是按照我个人喜好添加的。 615 | 616 | 将上面的配置添加到 ``~/.bashrc`` 的末尾,然后将下面的命令运行一次: 617 | 618 | :: 619 | 620 | $ source ~/.bashrc 621 | 622 | 如果你关闭所有的shell窗口和标签,然后再打开一个新的shell窗口或标签时, ``~/.bashrc`` 也会被执行,此时将会自动的更新你的 ``virtualenvwrapper`` 配置。 623 | 效果就跟执行上面的命令一样。 624 | 625 | 新建/激活/关闭/删除虚拟空间需要执行下面的命令: 626 | 627 | :: 628 | 629 | $ mkvirtualenv my_project_venv 630 | 631 | $ workon my_project_venv 632 | 633 | $ deactivate 634 | 635 | $ rmvirtualenv my_project_venv 636 | 637 | *Tab补全在virtualenvwrapper中是可用的哦~* 638 | 639 | 前往 `virtualenvwrapper 主页`_ 查找更多关于它的信息。 640 | 641 | .. _`virtualenvwrapper 主页`: http://www.doughellmann.com/projects/virtualenvwrapper/ 642 | 643 | 644 | 通过pip和virtualenv进行依赖管理 645 | ------------------------------- 646 | 647 | ``pip`` 结合 ``virtualenv`` 可以为你的项目提供基本的依赖管理。 648 | 649 | 你可以通过 ``pip freeze`` 命令来查看当前已安装的包版本。下面列出的是我写着个博客所用到的包的版本: 650 | 651 | :: 652 | 653 | $ pip freeze -l 654 | 655 | Jinja2==2.6 656 | 657 | PyYAML==3.10 658 | 659 | Pygments==1.4 660 | 661 | distribute==0.6.19 662 | 663 | markdown2==1.0.1.19 664 | 665 | 注意 ``-l`` 选项,它告诉 ``pip`` 只导出当前活动虚拟空间中安装的包,排除那些全局空间安装的包。 666 | 667 | 你可以把结果保存到文件里,然后将它添加到你的版本控制系统里。 668 | 669 | :: 670 | 671 | $ pip freeze -l > requirements.txt 672 | 673 | 同时 ``pip`` 也能从一个包含 ``pip freeze`` 命令的文件中安装包。 674 | 675 | :: 676 | 677 | $ pip install -r requirements.txt 678 | 679 | 680 | 其他重要工具 681 | ============ 682 | 683 | 虽然我们讨论了基本的Python版本,虚拟机和包管理,但在日常工作中我们仍然还需要一些专用的工具来完成任务。 684 | 尽管我不能把每一个工具的细节都讲到,然而我还是尽量给你提供基本的概述。 685 | 686 | 编辑器 687 | ------ 688 | 689 | 对于Python编程有大量很优秀的编译器。对于我个人而言,我更倾向于Vim,但这里我并不想挑起一场 *编辑器战争* 。 690 | 691 | 有大量支持Python的编辑器,例如:Vim/Gvim, Emacs, GNOME上的GEdit, 692 | KDE上的Kate, Scribes, ActiveState的Komodo Edit/IDE, WingWare的Wing IDE, 693 | JetBrains上PyCharm, Eclipse的PyDEV插件。此外,还有其他,但这些似乎是最流行的。你可以任意选择最适合你的。 694 | 695 | 696 | Pyflakes:源码检测工具 697 | ---------------------- 698 | 699 | Pyflakes是一个检查Python源码并通过文本分析找出错误的工具。 700 | 它可以检测出语法错误,和(部分)逻辑错误,导入但未使用的模块,只使用一次的变量,等等。 701 | 702 | 你可以通过 ``pip`` 安装: 703 | 704 | :: 705 | 706 | $ pip install pyflakes 707 | 708 | 在命令行调用它,参数填源文件名即可,如下所示: 709 | 710 | :: 711 | 712 | $ pyflakes filename.py 713 | 714 | Pyflakes也可已被集成进编辑器。这是它在我的vim中的样子。注意红波浪线: 715 | 716 | .. image:: images/vim-pyflakes.png 717 | 718 | 719 | 请自行前往Stack Overflow找出如何将Pyflakes添加到编辑器。 720 | 721 | `Pyflakes官网`_ 722 | 723 | .. _`Pyflakes官网`: https://launchpad.net/pyflakes 724 | 725 | 726 | Requests:一个HTTP库 727 | ------------------- 728 | 729 | Requests是一个将处理HTTP请求变得轻而易举的库。 730 | 731 | 同样是通过 ``pip`` 安装它: 732 | 733 | :: 734 | 735 | $ pip install requests 736 | 737 | 下面是一个例子: 738 | 739 | :: 740 | 741 | >>> import requests 742 | 743 | >>> r = requests.get('https://api.github.com', auth=('user', 'pass')) 744 | 745 | >>> r.status_code 746 | 747 | 204 748 | 749 | >>> r.headers['content-type'] 750 | 751 | 'application/json' 752 | 753 | >>> r.content 754 | 755 | ... 756 | 757 | `Requests文档`_ 758 | 759 | .. _`Requests文档`: http://docs.python-requests.org/en/latest/index.html 760 | 761 | 762 | Flask:一个web开发的微框架 763 | -------------------------- 764 | 765 | Flask是一个基于Werkzeug和Jinja2的微框架。 766 | 767 | 通过 ``pip`` 安装: 768 | 769 | :: 770 | 771 | $ pip install Flask 772 | 773 | 这是一个简单的例子: 774 | 775 | :: 776 | 777 | from flask import Flask 778 | 779 | app = Flask(__name__) 780 | 781 | 782 | 783 | @app.route("/") 784 | 785 | def hello(): 786 | 787 | return "Hello World!" 788 | 789 | 790 | 791 | if __name__ == "__main__": 792 | 793 | app.run() 794 | 795 | 796 | 可以这样运行它: 797 | 798 | :: 799 | 800 | $ python hello.py 801 | 802 | * Running on http://localhost:5000/ 803 | 804 | `Flask官网`_ 805 | 806 | .. _`Flask官网`: http://flask.pocoo.org/ 807 | 808 | 809 | Django:一个全栈式web开发框架 810 | ---------------------------- 811 | 812 | Django是一个全栈式web开发框架。它提供了ORM,HTTP库,表单处理,XSS过滤,模板和别的特性。 813 | 814 | 通过 ``pip`` 安装: 815 | 816 | :: 817 | 818 | $ pip install Django 819 | 820 | 去 `Django官网`_ 查找更多信息。 821 | 822 | .. _`Django官网`: http://djangoproject.com/ 823 | 824 | 825 | Fabric:简化SSH的使用并部署系统管理员任务 826 | ---------------------------------------- 827 | 828 | Fabric是一个命令行工具用来简化程序对于SSH的使用或运行系统管理员任务。 829 | 它提供了一个基本套件可以执行本地或远程shell命令(正常或通过sudo),上传/下载文件,以及其他辅助功能,如提示用户输入,或中止执行的操作。 830 | 831 | 可以通过 ``pip`` 安装: 832 | 833 | :: 834 | 835 | $ pip install fabric 836 | 837 | 这是一个通过Fabric写的任务: 838 | 839 | :: 840 | 841 | from fabric.api import run 842 | 843 | 844 | 845 | def host_type(): 846 | 847 | run('uname -s') 848 | 849 | 你可以在一台或多台服务器上执行这个命令: 850 | 851 | :: 852 | 853 | $ fab -H localhost host_type 854 | 855 | [localhost] run: uname -s 856 | 857 | [localhost] out: Linux 858 | 859 | 860 | 861 | Done. 862 | 863 | Disconnecting from localhost... done. 864 | 865 | `Fabric官网`_ 866 | 867 | .. _`Fabric官网`: http://fabfile.org/ 868 | 869 | 870 | SciPy:一个科学计算库 871 | -------------------- 872 | 873 | 如果你的工作涉及科学和数值计算,SciPy的是您不可或缺的重要工具。 874 | 875 | SciPy官网这样介绍: 876 | 877 | SciPy的(读做“Sigh Pie”)是数学、科学和工程方面的开源库。 878 | 这也是Python在数值计算方面非常优秀的一个库。 879 | SciPy的库依赖于NumPy,它提供了方便快速的N维矩阵操作。 880 | SciPy库与NumPy中的矩阵兼容,并提供了许多用户友好且高效率的数值程序,如数值的积分和优化。 881 | 同时,他们运行在所有流行的操作系统上,安装快速,并且都是免费的。NumPy和SciPy易于使用,但功能强大,足以满足一些世界领先的科学家和工程师。 882 | 如果您需要在电脑上处理数字、显示或公布结果,试试SciPy吧! 883 | 884 | `SciPy`_ 885 | 886 | .. _`SciPy`: http://www.scipy.org/ 887 | 888 | 889 | PEP 8:Python风格指南 890 | -------------------- 891 | 892 | 虽然它本身不是一个软件工具,但它却是Python一个重要的资源。 893 | 894 | PEP 8是一个描述Python发行版中基本库的编码约定的文档。 895 | 这份文档的希望能够约定全世界Python开发者的代码布局,变量、类、函数的命名规则。 896 | 请确保你了解它,并遵循它。他将在未来的Python使用中带来相当多的益处。 897 | 898 | `PEP 0008`_ 899 | 900 | .. _`PEP 0008`: http://www.python.org/dev/peps/pep-0008/ 901 | 902 | 903 | 强大的Python标准库 904 | ------------------ 905 | 906 | Python的标准库涵盖非常广泛,提供各种各样的功能。 907 | 该库包含的内置模块(使用C编写的)提供了访问系统的功能,如文件I/O, 908 | 并且存在大量Python编写的模块,他们提供标准化的解决方案去解决日常的编程中出现的许多问题。 909 | 这些模块都明确地抽离平台的细节,提供平台无关的API,旨在加强Python程序的跨平台可移植性。 910 | 911 | 912 | 推荐阅读 913 | ======== 914 | 915 | David Goodger的 `Code Like a Pythonista: Idiomatic Python`_ 包含了很多实用的Python例子和技术。 916 | 917 | .. _`Code Like a Pythonista: Idiomatic Python` : http://python.net/~goodger/projects/pycon/2007/idiomatic/handout.html 918 | 919 | Doug Hellmann的 `Python Module of the Week` 系列的重点是建设一个使用Python标准库中的模块的示例代码的仓库。 920 | 921 | 922 | 赠言 923 | ==== 924 | 925 | 这个教程到目前为止,所讲述的仅是点到为止。Python世界中有大量的工具,库和软件可以帮你完成你的工作。 926 | 但你需要自己花时间去发现他们! 927 | 928 | Python有一个伟大的社区和一群很聪明的维护者,他们对于新手非常有耐心。 929 | 因此,关注你最喜欢的开源项目,加入他们的邮件列表,跟有经验的开发者交流经验。 930 | 不久的将来,你的经验也将足够丰富,你将会成为他们其中的一员。 931 | 932 | 933 | 最后我想引用下 **Zen Of Python** 。我们思考,学习,受到启发! 934 | *Happy Pythoning* 935 | 936 | :: 937 | 938 | >>> import this 939 | 940 | The Zen of Python, by Tim Peters 941 | 942 | 943 | 944 | Beautiful is better than ugly. 945 | 946 | Explicit is better than implicit. 947 | 948 | Simple is better than complex. 949 | 950 | Complex is better than complicated. 951 | 952 | Flat is better than nested. 953 | 954 | Sparse is better than dense. 955 | 956 | Readability counts. 957 | 958 | Special cases aren't special enough to break the rules. 959 | 960 | Although practicality beats purity. 961 | 962 | Errors should never pass silently. 963 | 964 | Unless explicitly silenced. 965 | 966 | In the face of ambiguity, refuse the temptation to guess. 967 | 968 | There should be one-- and preferably only one --obvious way to do it. 969 | 970 | Although that way may not be obvious at first unless you're Dutch. 971 | 972 | Now is better than never. 973 | 974 | Although never is often better than *right* now. 975 | 976 | If the implementation is hard to explain, it's a bad idea. 977 | 978 | If the implementation is easy to explain, it may be a good idea. 979 | 980 | Namespaces are one honking great idea -- let's do more of those! 981 | --------------------------------------------------------------------------------