简单的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实现的简单发送邮件脚本分享
Nov 07 Python
Python入门之三角函数sin()函数实例详解
Nov 08 Python
python交互式图形编程实例(二)
Nov 17 Python
PyTorch线性回归和逻辑回归实战示例
May 22 Python
利用Python写一个爬妹子的爬虫
Jun 08 Python
Python统计python文件中代码,注释及空白对应的行数示例【测试可用】
Jul 25 Python
Django异步任务之Celery的基本使用
Mar 23 Python
python实现的生成word文档功能示例
Aug 23 Python
Python 生成一个从0到n个数字的列表4种方法小结
Nov 28 Python
Python函数参数分类原理详解
May 28 Python
python正则表达式re.match()匹配多个字符方法的实现
Jan 27 Python
简述python四种分词工具,盘点哪个更好用?
Apr 13 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获取CSS文件中图片地址并下载到本地的方法
2014/12/02 PHP
Zend Framework数据库操作方法实例总结
2016/12/11 PHP
php7新特性的理解和比较总结
2019/04/14 PHP
JavaScript 在网页上单击鼠标的地方显示层及关闭层
2012/12/30 Javascript
通过一段代码简单说js中的this的使用
2013/07/23 Javascript
JS.elementGetStyle(element, style)应用示例
2013/09/24 Javascript
jquery slibings选取同级其他元素的实现代码
2013/11/15 Javascript
jquery实现的美女拼图游戏实例
2015/05/04 Javascript
c#程序员对TypeScript的认识过程
2015/06/19 Javascript
js实现固定宽高滑动轮播图效果
2017/01/13 Javascript
vue使用watch 观察路由变化,重新获取内容
2017/03/08 Javascript
jquery实现企业定位式导航效果
2018/01/01 jQuery
浅析vue中常见循环遍历指令的使用 v-for
2018/04/18 Javascript
详解nuxt路由鉴权(express模板)
2018/11/21 Javascript
node.js 微信开发之定时获取access_token
2020/02/07 Javascript
JS前端基于canvas给图片添加水印
2020/11/11 Javascript
使用Python写CUDA程序的方法
2017/03/27 Python
Python中查看文件名和文件路径
2017/03/31 Python
使用python绘制3维正态分布图的方法
2018/12/29 Python
简单了解python元组tuple相关原理
2019/12/02 Python
Python实现企业微信机器人每天定时发消息实例
2020/02/25 Python
python属于跨平台语言码
2020/06/09 Python
python 下载文件的几种方法汇总
2021/01/06 Python
处理textarea中的换行和空格
2019/12/12 HTML / CSS
牵手50台湾:专为黄金岁月的单身人士而设的交友网站
2021/02/18 全球购物
计算机科学与技术应届生求职信
2013/11/07 职场文书
本科生职业生涯规划书范文
2014/01/21 职场文书
村官工作鉴定评语
2014/01/27 职场文书
公司营业员的自我评价
2014/03/04 职场文书
学生期末评语大全
2014/04/30 职场文书
环保建议书100字
2014/05/14 职场文书
门面房租房协议书
2014/08/20 职场文书
甘南现象心得体会
2014/09/11 职场文书
幼儿园教师个人工作总结2015
2015/05/12 职场文书
分享Python获取本机IP地址的几种方法
2022/03/17 Python
Python利用FlashText算法实现替换字符串
2022/03/31 Python