在刚开始学习Python的时候,有一些事情我希望早点知道。我花了很多时间来学习这些东西。我想将所有这些要点整理成一篇文章。本文的目标读者是刚开始学习Python语言并希望跳过前几个月使用他们已经使用的类似工具学习Python的有经验的程序员。关于包管理和标准工具的部分也对初学者有帮助。我的经验主要基于Python2.7,但大多数工具都适用于任何版本。如果你从未使用过Python,我强烈建议你阅读Python介绍,因为你需要了解基本的语法和类型。包管理Python世界的一大优点是大量的第三方包。此外,管理这些包非常容易。按照惯例,项目所需的包都列在requirements.txt文件中。每个包一行,通常包括版本号。这是一个例子,这个博客使用Pelican:;html-script:false]pelican==3.3Markdownpelican-extended-sitemap==1.0.0Python包的一个缺陷是它们默认安装在全局范围内。我们将使用一个工具,让我们的每个项目都有一个独立的环境,这个工具叫做virtualenv。我们还需要安装一个更高级的包管理工具pip,它可以与virtualenv一起工作。首先,我们需要安装pip。大多数python安装器都内置了easy_install(python默认的包管理工具),所以我们使用easy_installpip来安装pip。这应该是您最后一次使用easy_install。如果您没有安装easy_install,它似乎可以从linux系统上的python-setuptools包中获得。如果您使用的是Python3.3或更高版本,那么Virtualenv已经是标准库的一部分,因此无需安装它。接下来,您要安装virtualenv和virtualenvwrapper。Virtualenv使您能够为每个项目创建一个隔离的环境。当您的不同项目使用不同版本的包时,这尤其有用。Virtualenv包装器提供了一些不错的脚本来使事情变得更容易。Shell;html-script:false]sudopipinstallvirtualenvwrapper安装virtualenvwrapper时,它会将virtualenv列为依赖包,因此会自动安装。打开一个新的shell并键入mkvirtualenvtest。如果你打开另一个shell,你不在这个virtualenv中,你可以通过workontest来启动它。工作完成后,您可以使用deactivate来停用。IPythonIPython是标准Python交互式编程环境的替代品,支持自动完成、快速访问文档以及许多其他标准交互式编程环境应具备的功能。当你在虚拟环境中时,你可以简单地使用pipinstallipython来安装它,并在命令行中使用ipython来启动它。另一个不错的功能是“笔记本”,它需要额外的组件。安装完成后就可以使用ipythonnotebook了,会出现一个漂亮的webUI,可以在这里创建notebook。这在科学计算中很流行。对于测试,我建议使用nose或py.test。我大部分时间都用鼻子。他们基本上是相似的。我将解释鼻子的一些细节。这是一个使用鼻子进行测试的可笑的人为示例。以test_开头的文件中所有以test_开头的函数都会被调用:Python;html-script:false]deftest_equality():assertTrue==False正如预期的那样,当运行nose时,我们的测试没有通过。Shell;html-script:false](test)jhaddad@jons-mac-pro~VIRTUAL_ENV/src$nosetestsF==========================================================================失败:test_nose_example.test_equality-----------------------------------------------------------------追溯(mostrecentcallast):文件“/Users/jhaddad/.virtualenvs/test/lib/python2.7/site-packages/nose/case.py",line197,inrunTestself.test(*self.arg)File"/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py",line3,intest_equalityassertTrue==FalseAssertionError------------------------------------------------------------------nose.tools还有一些方便的方法可以调用。Python;html-script:false]fromnose.toolsimportassert_truedeftest_equality():assert_true(False)如果你想使用更像JUnit的方法,也可以:Python;html-script:false]fromnose.toolsimportassert_truefromunittestimportTestCaseclassExampleTest(TestCase):defsetUp(self):#setUp&tearDownarebothavailableself.blah=Falsedefest_blah(self):self.assertTrue(self.blah)开始测试:Shell;html-script:false](test)jhaddad@jons-mac-pro~VIRTUAL_ENV/src$nosetestsF========================================================================失败:test_blah(test_nose_example.ExampleTest)------------------------------------------------------------------------回溯(mostrecentcallast):文件“/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py”,第11行,intest_blahself.assertTrue(self.blah)AssertionError:Falseisnottrue--------------------------------------------------------------------Ran1testin0.003sFAILED(failures=1)优秀的Mock库包含在Python3中,但是如果你你正在使用Python2,你可以使用pypi来获取它。这个测试会进行远程调用,但是这个调用会耗时10s。这个例子显然是人为设计的。我们使用模拟来返回示例数据,而不是实际进行调用。Python;html-script:false]importmockfrommockimportpatchfromtimeimportsleepclassSweetness(object):defslow_remote_call(self):sleep(10)return"some_data"#letspretendwegetthisbackfromourremoteapicalldeftest_long_call():s=Sweetness()result==some.slow_remote_call()assert_call()当然,我们的测试需要很长时间。Shell;html-script:false](test)jhaddad@jons-mac-pro~VIRTUAL_ENV/src$noseteststest_mock.pyRan1testin10.001sOK太慢了!所以我们问自己,我们在测试什么?我们需要测试远程调用是否有效,或者我们是在测试拿到数据后要做什么?多半是后者。让我们摆脱这个愚蠢的远程调用:Python;html-script:false]importmockfrommockimportpatchfromtimeimportsleepclassSweetness(object):defslow_remote_call(self):sleep(10)return"some_data"#letspretendwegetthisbackfromourremoteapicalldeftest_long_call():s=Sweetness。s,"slow_remote_call",return_value="some_data"):result=s.slow_remote_call()assertresult="some_data"那我们再试一次:Shell;html-script:false](test)jhaddad@jons-mac-pro~VIRTUAL_ENV/src$noseteststest_mock.py.-------------------------------------------------------------------Ran1testin0.001sOK好多了。请记住,这个例子被简化得可笑。就个人而言,我只忽略来自远程系统的调用,而不是我的数据库调用。nose-progressive是一个很棒的模块,它可以改进nose的输出,以便在错误发生时显示错误,而不是等到***。如果您的测试需要一定的时间,这是一件好事。pipinstallnose-progressive并添加--with-progressive到你的nosetests调试iPDB是一个很好的工具,我发现了很多令人难以置信的错误。pipinstallipdb安装工具,然后importipdb;ipdb.set_trace()在你的代码中,你会在程序运行时得到一个很好的交互式提示。它一次一行地执行程序并检查变量。Python有一个很好的内置跟踪模块,可以帮助我弄清楚发生了什么。这里是一个无用的python程序:Python;html-script:false]a=1b=2a=b这里是这个程序的跟踪结果:Shell;html-script:false](test)jhaddad@jons-mac-pro~VIRTUAL_ENV/src$python-mtrace--tracetracing.py1?---modulename:tracing,funcname:
