写给已有编程经验的 Python 初学者的总结

当我开始学习Python的时候,有些事我希望我一早就知道。我花费了很多时间才学会这些东西。我想要把这些重点都编纂到一篇文章当中。这篇文章的目标读者,是刚刚开始学习Python语言的有经验的程序员,想要跳过前几个月研究Python使用的那些他们已经在用的类似工具。包管理和标准工具这两节对于初学者来说同样很有帮助。

我的经验主要基于Python 2.7,但是大多数的工具对任何版本都有效。

如果你从来没有使用过Python,我强烈建议你阅读Python introduction,因为你需要知道基本的语法和类型。

包管理

Python世界最棒的地方之一,就是大量的第三方程序包。同样,管理这些包也非常容易。按照惯例,会在 requirements.txt 文件中列出项目所需要的包。每个包占一行,通常还包含版本号。这里有一个例子,本博客使用Pelican:

Python代码

  1. pelican==3.3
  2. Markdown
  3. pelican-extended-sitemap==1.0.0

Python 程序包有一个缺陷是,它们默认会进行全局安装。我们将要使用一个工具,使我们每个项目都有一个独立的环境,这个工具叫virtualenv。我们同样要安装一个更高级的包管理工具,叫做pip,他可以和virtualenv配合工作。

首先,我们需要安装pip。大多数python安装程序已经内置了easy_install(python默认的包管理工具),所以我们就使用easy_install pip来安装pip。这应该是你最后一次使用easy_install 了。如果你并没有安装easy_install ,在linux系统中,貌似从python-setuptools 包中可以获得。

如果你使用的Python版本高于等于3.3, 那么Virtualenv 已经是标准库的一部分了,所以没有必要再去安装它了。

下一步,你希望安装virtualenv和virtualenvwrapper。Virtualenv使你能够为每个项目创造一个独立的环境。尤其是当你的不同项目使用不同版本的包时,这一点特别有用。Virtualenv
wrapper 提供了一些不错的脚本,可以让一些事情变得容易。

Python代码

  1. sudo pip install virtualenvwrapper

当virtualenvwrapper安装后,它会把virtualenv列为依赖包,所以会自动安装。

打开一个新的shell,输入mkvirtualenv test 。如果你打开另外一个shell,则你就不在这个virtualenv中了,你可以通过workon test 来启动。如果你的工作完成了,可以使用deactivate 来停用。

IPython

IPython是标准Python交互式的编程环境的一个替代品,支持自动补全,文档快速访问,以及标准交互式编程环境本应该具备的很多其他功能。

当你处在一个虚拟环境中的时候,可以很简单的使用pip install ipython 来进行安装,在命令行中使用ipython 来启动

另一个不错的功能是”笔记本”,这个功能需要额外的组件。安装完成后,你可以使用ipython notebook,而且会有一个不错的网页UI,你可以创建笔记本。这在科学计算领域很流行。

测试

我推荐使用nose或是py.test。我大部分情况下用nose。它们基本上是类似的。我将讲解nose的一些细节。

这里有一个人为创建的可笑的使用nose进行测试的例子。在一个以test_开头的文件中

Python代码

  1. 的所有以test_开头的函数,都会被调用:
  2. def test_equality():
  3. assert True == False

不出所料,当运行nose的时候,我们的测试没有通过。

nose.tools中同样也有一些便捷的方法可以调用

Python代码

  1. from nose.tools import assert_true
  2. def test_equality():
  3. assert_true(False)

如果你想使用更加类似JUnit的方法,也是可以的:

Python代码

  1. from nose.tools import assert_true
  2. from unittest import TestCase
  3. class ExampleTest(TestCase):
  4. def setUp(self): # setUp & tearDown are both available
  5. self.blah = False
  6. def test_blah(self):
  7. self.assertTrue(self.blah)

开始测试:

Python代码

  1. (test)[email protected] ~VIRTUAL_ENV/src$ nosetests
  2. F
  3. ======================================================================
  4. FAIL: test_blah (test_nose_example.ExampleTest)
  5. ----------------------------------------------------------------------
  6. Traceback (most recent call last):
  7. File "/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py", line 11, in test_blah
  8. self.assertTrue(self.blah)
  9. AssertionError: False is not true
  10. ----------------------------------------------------------------------
  11. Ran 1 test in 0.003s
  12. FAILED (failures=1)

卓越的Mock库包含在Python 3 中,但是如果你在使用Python
2,可以使用pypi来获取。这个测试将进行一个远程调用,但是这次调用将耗时10s。这个例子显然是人为捏造的。我们使用mock来返回样本数据而不是真正的进行调用。

Python代码

  1. import mock
  2. from mock import patch
  3. from time import sleep
  4. class Sweetness(object):
  5. def slow_remote_call(self):
  6. sleep(10)
  7. return "some_data" # lets pretend we get this back from our remote api call
  8. def test_long_call():
  9. s = Sweetness()
  10. result = s.slow_remote_call()
  11. assert result == "some_data"

当然,我们的测试需要很长的时间。

Python代码

  1. (test)[email protected] ~VIRTUAL_ENV/src$ nosetests test_mock.py
  2. Ran 1 test in 10.001s
  3. OK

太慢了!因此我们会问自己,我们在测试什么?我们需要测试远程调用是否有用,还是我们要测试当我们获得数据后要做什么?大多数情况下是后者。让我们摆脱这个愚蠢的远程调用吧:

Python代码

  1. import mock
  2. from mock import patch
  3. from time import sleep
  4. class Sweetness(object):
  5. def slow_remote_call(self):
  6. sleep(10)
  7. return "some_data" # lets pretend we get this back from our remote api call
  8. def test_long_call():
  9. s = Sweetness()
  10. with patch.object(s, "slow_remote_call", return_value="some_data"):
  11. result = s.slow_remote_call()
  12. assert result == "some_data"

好吧,让我们再试一次:

Python代码

  1. (test)[email protected] ~VIRTUAL_ENV/src$ nosetests test_mock.py
  2. .
  3. ----------------------------------------------------------------------
  4. Ran 1 test in 0.001s
  5. OK

好多了。记住,这个例子进行了荒唐的简化。就我个人来讲,我仅仅会忽略从远程系统的调用,而不是我的数据库调用。

nose-progressive是一个很好的模块,它可以改善nose的输出,让错误在发生时就显示出来,而不是留到最后。如果你的测试需要花费一定的时间,那么这是件好事。

pip install nose-progressive 并且在你的nosetests中添加--with-progressive

调试

iPDB是一个极好的工具,我已经用它查出了很多匪夷所思的bug。pip install ipdb 安装该工具,然后在你的代码中import ipdb; ipdb.set_trace(),然后你会在你的程序运行时,获得一个很好的交互式提示。它每次执行程序的一行并且检查变量。

python内置了一个很好的追踪模块,帮助我搞清楚发生了什么。这里有一个没什么用的python程序:

Python代码

  1. a = 1
  2. b = 2
  3. a = b

这里是对这个程序的追踪结果:

Python代码

  1. (test)[email protected] ~VIRTUAL_ENV/src$ python -m trace --trace tracing.py                                                                                                        1 ?
  2. --- modulename: tracing, funcname: <module>
  3. tracing.py(1): a = 1
  4. tracing.py(2): b = 2
  5. tracing.py(3): a = b
  6. --- modulename: trace, funcname: _unsettrace
  7. trace.py(80):         sys.settrace(None)

当你想要搞清楚其他程序的内部构造的时候,这个功能非常有用。如果你以前用过strace,它们的工作方式很相像

在一些场合,我使用pycallgraph来追踪性能问题。它可以创建函数调用时间和次数的图表。

最后,objgraph对于查找内存泄露非常有用。这里有一篇关于如何使用它查找内存泄露的好文。

Gevent

Gevent 是一个很好的库,封装了Greenlets,使得Python具备了异步调用的功能。是的,非常棒。我最爱的功能是Pool,它抽象了异步调用部分,给我们提供了可以简单使用的途径,一个异步的map()函数:

Python代码

  1. from gevent import monkey
  2. monkey.patch_all()
  3. from time import sleep, time
  4. def fetch_url(url):
  5. print "Fetching %s" % url
  6. sleep(10)
  7. print "Done fetching %s" % url
  8. from gevent.pool import Pool
  9. urls = ["http://test.com", "http://bacon.com", "http://eggs.com"]
  10. p = Pool(10)
  11. start = time()
  12. p.map(fetch_url, urls)
  13. print time() - start

非常重要的是,需要注意这段代码顶部对gevent monkey进行的补丁,如果没有它的话,就不能正确的运行。如果我们让Python连续调用 fetch_url 3次,通常我们期望这个过程花费30秒时间。使用gevent:

Python代码

  1. (test)[email protected] ~VIRTUAL_ENV/src$ python g.py
  2. Fetching http://test.com
  3. Fetching http://bacon.com
  4. Fetching http://eggs.com
  5. Done fetching http://test.com
  6. Done fetching http://bacon.com
  7. Done fetching http://eggs.com
  8. 10.001791954

如果你有很多数据库调用或是从远程URLs获取,这是非常有用的。我并不是很喜欢回调函数,所以这一抽象对我来说效果很好。

结论

好吧,如果你看到这里了,那么你很可能已经学到了一些新东西。这些工具,在过去的一年里对我影响重大。找打它们花费了不少时间,所以希望本文能够减少其他人想要很好利用这门语言需要付出的努力。

时间: 2024-11-02 09:52:35

写给已有编程经验的 Python 初学者的总结的相关文章

Python/Numpy大数据编程经验

Python/Numpy大数据编程经验 1.边处理边保存数据,不要处理完了一次性保存.不然程序跑了几小时甚至几天后挂了,就啥也没有了.即使部分结果不能实用,也可以分析程序流程的问题或者数据的特点. 2. 及时用 del 释放大块内存.Python缺省是在变量范围(variablescope)之外才释放一个变量,哪怕这个变量在后面的代码没有再被用到,所以需要手动释放大的array. 注意所有对数组的引用都del之后,数组才会被del.这些引用包括A[2:]这样的view,即使np.split也只是

【Python】初学编程适合学Python?其有何用?

初学编程适合学Python?其有何用? 作者:白宁超 2016年10月4日19:59:39 摘要:python语言俨然不算新技术,七八年前甚至更早已有很多人研习,只是没有现在流行罢了.之所以当下如此盛行,我想肯定是多因素造成了,当然市场需求的重要因素.吴军博士对大数据流行的解释与python流行或许有些默契.数据一直以来都存在,只是在历史条件下,由于计算性能和技术发展的原因,与之匹配的数据处理技术还不是很先进,以至于很多数据被我们舍弃了.同样,python语言简洁流畅等多种优点,也会让第一次接触

牢记20条编程经验

http://article.yeeyan.org/view/184220/150437 原文作者乔纳森·丹尼可(JonathanDanylko)是一位自由职业的Web架构师和程序员,编程经验已超过20年 1. 估算解决问题所需要的时间.不要怕,承认吧!我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时.为自己定一个时间限制吧,1小时.30分钟或甚至15分钟.如果在这期间你不能解决问题,那就去寻求帮助,或到网上找答案,而不是尝试去做“超级堆码员”. 2. 编程语言是一种语言,只是一种语

编程经验

所谓高手,就是说他在模仿的过程中不断比较自己写的东西和框架本身的差异,不断发现问题,想尽办法解决问题,思考得越多,你碰到的问题就会越多,这是一个正向循环,最终你的技术能力就会螺旋式的上升:而低手只会被动的等待问题,一旦问题自己觉得解决得差不多就放下了,这样自然就不会产生更多的问题,最终技术能力就始终停留在那个菜鸟阶段 1. 估算解决问题所需要的时间.不要怕,承认吧!我曾见过一些程序员为了解决一个特殊问题而坐在显示器前面8小时.为自己定一个时间限制吧,1小时.30分钟或甚至15分钟.如果在这期间你

20年资深程序员编程经验分享

原文作者乔纳森·丹尼可(Jonathan Danylko)是一位自由职业的web架构师和程序员,编程经验已超过20年,涉足领域有电子商务.生物技术.房地产.医疗.保险和公用事业. 从11岁时,我就一直在编程,并且一直都很喜欢技术和编程.这些年来,我积累了一些艰难又容易的经验.作为一名程序员,你或许还没这些经验,但我会把它们献给那些想从中学到更多的朋友. 虽然我想我会持续更新这些经验,可能还会有更多的感想,但就我这20年来看,我想下面这个列表中基本不需要增添额外的东西了.下面就是我至今最难忘的经验

[转载]风雨20年:我所积累的20条编程经验

原文作者乔纳森·丹尼可(Jonathan Danylko)是一位自由职业的web架构师和程序员,编程经验已超过20年,涉足领域有电子商务.生物技术.房地产.医疗.保险和公用事业.正如乔纳 森在文中所言,本文适合刚毕业的大学生和刚入门的程序员.如果你已是高级开发人员,或许你在本文中看到自己的身影. 从11岁时,我就一直在编程,并且一直都很喜欢技术和编程.这些年来,我积累了一些艰难又容易的经验.作为一名程序员,你或许还没这些经验,但我会把它们献给那些想从中学到更多的朋友. 我会持续更新这些经验,我可

代写大作业、代写大学计算机基础编程

代写大作业.代写大学计算机基础编程<大学计算机基础>常规班大作业题目 要求:从下列题目中,选择1道题目作为大作业,实现程序并撰写实验报告:文科学生可以选做任何题目,理科学生不可以选做"文科题目". 作业一 信息录入与查找系统 设计一个信息录入与查找系统,使其具有基本身份信息的录入功能,并能在录入的数据中根据一个或多个查找关键字查询出所有符合条件的人.具体要求如下: 1. 设计一个 GUI 界面,其中具有多个输入框,对应姓名.性别.年龄.血型.星座.身高.体重等数据:并有确定

Python黑帽编程2.1 Python编程哲学

Python黑帽编程2.1  Python编程哲学 本节的内容有些趣味性,涉及到很多人为什么会选择Python,为什么会喜欢这门语言.我带大家膜拜下Python作者的Python之禅,然后再来了解下Python的编程规范. 2.1.1 ZEND OF PYTHON 在Kali中启动终端,输入Python,进入交互模式. 图2 输入命令 import this “一首诗”呈现在我们眼前. 图3 内容如下: Beautiful is better than ugly.       优美胜于丑陋 Ex

前端编程经验的总结

功能界面设计,涉及到的技术有前端的CSS+DIV布局,以前布局使用表格,框架,现在布局基本上 使用区块的浮动布局. 功能界面实际的一般思路是: >1. 首先是要有项目的需求分析,完成需求说明的文档,这个部分右需求分析是完成. >2. 功能界面的设计,这部分由美工和网站策划师完成. >3. 前端工程师完成功能界面的实现,必须分毫不差的实现美工的效果. >4. 布局完成,渲染完成之后,即可以为表单添加特效,校验及其他的特效等,也就是      前端工程师的脚本编程. >5. 有些