简单的Python2.7编程初学经验总结


Posted in Python onApril 01, 2015

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

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

pelican==3.3
Markdown
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 提供了一些不错的脚本,可以让一些事情变得容易。

sudo pip install virtualenvwrapper

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

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

简单的Python2.7编程初学经验总结

IPython

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

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

简单的Python2.7编程初学经验总结

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

简单的Python2.7编程初学经验总结

测试

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

这里有一个人为创建的可笑的使用nose进行测试的例子。在一个以test_开头的文件中的所有以test_开头的函数,都会被调用:
 

def test_equality():
  assert True == False

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

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ nosetests                                                                   
F
======================================================================
FAIL: test_nose_example.test_equality
----------------------------------------------------------------------
Traceback (most recent call last):
 File "/Users/jhaddad/.virtualenvs/test/lib/python2.7/site-packages/nose/case.py", line 197, in runTest
  self.test(*self.arg)
 File "/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py", line 3, in test_equality
  assert True == False
AssertionError
 
----------------------------------------------------------------------

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

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

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

from nose.tools import assert_true
from unittest import TestCase
 
class ExampleTest(TestCase):
 
  def setUp(self): # setUp & tearDown are both available
    self.blah = False
 
  def test_blah(self):
    self.assertTrue(self.blah)

开始测试:
 

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ nosetests                                                                   
F
======================================================================
FAIL: test_blah (test_nose_example.ExampleTest)
----------------------------------------------------------------------
Traceback (most recent call last):
 File "/Users/jhaddad/.virtualenvs/test/src/test_nose_example.py", line 11, in test_blah
  self.assertTrue(self.blah)
AssertionError: False is not true
 
----------------------------------------------------------------------
Ran 1 test in 0.003s
 
FAILED (failures=1)

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

import mock
 
from mock import patch
from time import sleep
 
class Sweetness(object):
  def slow_remote_call(self):
    sleep(10)
    return "some_data" # lets pretend we get this back from our remote api call
 
def test_long_call():
  s = Sweetness()
  result = s.slow_remote_call()
  assert result == "some_data"

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

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ nosetests test_mock.py                                                            
 
Ran 1 test in 10.001s
 
OK

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

import mock
 
from mock import patch
from time import sleep
 
class Sweetness(object):
  def slow_remote_call(self):
    sleep(10)
    return "some_data" # lets pretend we get this back from our remote api call
 
def test_long_call():
  s = Sweetness()
  with patch.object(s, "slow_remote_call", return_value="some_data"):
    result = s.slow_remote_call()
  assert result == "some_data"

好吧,让我们再试一次:
 

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ nosetests test_mock.py                                                            
.
----------------------------------------------------------------------
Ran 1 test in 0.001s
 
OK

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

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

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

简单的Python2.7编程初学经验总结

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

a = 1
b = 2
a = b

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

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ python -m trace --trace tracing.py                                                    1 ? 
 --- modulename: tracing, funcname: <module>
tracing.py(1): a = 1
tracing.py(2): b = 2
tracing.py(3): a = b
 --- modulename: trace, funcname: _unsettrace
trace.py(80):     sys.settrace(None)

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

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

简单的Python2.7编程初学经验总结

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

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

from gevent import monkey
monkey.patch_all()
 
from time import sleep, time
 
def fetch_url(url):
  print "Fetching %s" % url
  sleep(10)
  print "Done fetching %s" % url
 
from gevent.pool import Pool
 
urls = ["http://test.com", "http://bacon.com", "http://eggs.com"]
 
p = Pool(10)
 
start = time()
p.map(fetch_url, urls)
print time() - start

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

(test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ python g.py                                                                  
Fetching http://test.com
Fetching http://bacon.com
Fetching http://eggs.com
Done fetching http://test.com
Done fetching http://bacon.com
Done fetching http://eggs.com
10.001791954

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

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

Python 相关文章推荐
python设置检查点简单实现代码
Jul 01 Python
Python卸载模块的方法汇总
Jun 07 Python
python脚本爬取字体文件的实现方法
Apr 29 Python
python中numpy.zeros(np.zeros)的使用方法
Nov 07 Python
python中format()函数的简单使用教程
Mar 14 Python
python如何在列表、字典中筛选数据
Mar 19 Python
Python将文本去空格并保存到txt文件中的实例
Jul 24 Python
PyTorch: 梯度下降及反向传播的实例详解
Aug 20 Python
你还在@微信官方?聊聊Python生成你想要的微信头像
Sep 25 Python
Python3.7安装pyaudio教程解析
Jul 24 Python
Django配置Bootstrap, js实现过程详解
Oct 13 Python
用基于python的appium爬取b站直播消费记录
Apr 17 Python
极简的Python入门指引
Apr 01 #Python
分析在Python中何种情况下需要使用断言
Apr 01 #Python
用Python制作简单的朴素基数估计器的教程
Apr 01 #Python
简单的编程0基础下Python入门指引
Apr 01 #Python
python查找目录下指定扩展名的文件实例
Apr 01 #Python
Python利用多进程将大量数据放入有限内存的教程
Apr 01 #Python
python连接远程ftp服务器并列出目录下文件的方法
Apr 01 #Python
You might like
php中的登陆login
2007/01/18 PHP
PHP静态调用非静态方法的应用分析
2013/05/02 PHP
php验证码生成代码
2015/11/11 PHP
PHP读取文件的常见几种方法
2016/11/03 PHP
php layui实现前端多图上传实例
2019/07/30 PHP
用jquery ajax获取网站Alexa排名的代码
2009/12/12 Javascript
JavaScript 图片预览效果 推荐
2009/12/22 Javascript
IE6 fixed的完美解决方案
2011/03/31 Javascript
js隐藏与显示回到顶部按钮及window.onscroll事件应用
2013/01/25 Javascript
微信小程序前端源码逻辑和工作流
2016/09/25 Javascript
jQuery简单实现遍历单选框的方法
2017/03/06 Javascript
layui前段框架日期控件使用方法详解
2017/05/19 Javascript
移动端效果之Swiper详解
2017/10/09 Javascript
node.js使用express框架进行文件上传详解
2019/03/03 Javascript
vue实现多条件和模糊搜索功能
2019/05/28 Javascript
node实现简单的增删改查接口实例代码
2019/08/22 Javascript
解决vue做详情页跳转的时候使用created方法 数据不会更新问题
2020/07/24 Javascript
Python中利用Scipy包的SIFT方法进行图片识别的实例教程
2016/06/03 Python
python实现list元素按关键字相加减的方法示例
2017/06/09 Python
Python 获取当前所在目录的方法详解
2017/08/02 Python
python实现屏保程序(适用于背单词)
2019/07/30 Python
python多进程并发demo实例解析
2019/12/13 Python
一文弄懂Pytorch的DataLoader, DataSet, Sampler之间的关系
2020/07/03 Python
一款纯css3实现的响应式导航
2014/10/31 HTML / CSS
Nili Lotan官网:Nili Lotan同名品牌
2018/01/07 全球购物
GUESS Factory加拿大:牛仔裤、服装及配饰
2019/09/20 全球购物
英国在线药房和在线医生:LloydsPharmacy
2019/10/21 全球购物
介绍一下EJB的体系结构
2012/08/01 面试题
2014年元旦活动方案
2014/02/15 职场文书
党的群众路线教育实践活动个人整改方案
2014/10/25 职场文书
病人家属写给医院的感谢信
2015/01/23 职场文书
新郎接新娘保证书
2015/05/08 职场文书
社区安置帮教工作总结2015
2015/05/20 职场文书
远程教育集中轮训基层干部培训班学习心得体会
2016/01/09 职场文书
深度学习详解之初试机器学习
2021/04/14 Python
uniapp引入支付宝原生扫码插件步骤详解
2022/07/23 Javascript