简单的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基于phantomjs实现导入图片
May 13 Python
python+selenium+autoit实现文件上传功能
Aug 23 Python
用python处理图片之打开\显示\保存图像的方法
May 04 Python
python3 requests中使用ip代理池随机生成ip的实例
May 07 Python
解决PyCharm import torch包失败的问题
Oct 13 Python
对python创建及引用动态变量名的示例讲解
Nov 10 Python
详解python的四种内置数据结构
Mar 19 Python
python实现集中式的病毒扫描功能详解
Jul 09 Python
Python Numpy 自然数填充数组的实现
Nov 28 Python
python3 实现口罩抽签的功能
Mar 11 Python
opencv 形态学变换(开运算,闭运算,梯度运算)
Jul 07 Python
django学习之ajax post传参的2种格式实例
May 14 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获取当前日期和时间及格式化方法参数
2015/05/11 PHP
PHP 7.1中AES加解密方法mcrypt_module_open()的替换方案
2017/10/17 PHP
PHP mongodb操作类定义与用法示例【适合mongodb2.x和mongodb3.x】
2018/06/16 PHP
javascript之典型高阶函数应用介绍二
2013/01/10 Javascript
Jquery实现页面加载时弹出对话框代码
2013/04/19 Javascript
js倒计时小程序
2013/11/05 Javascript
javascript中取前n天日期的两种方法分享
2014/01/26 Javascript
JS字符串拼接在ie中都报错的解决方法
2014/03/27 Javascript
javascript原型模式用法实例详解
2015/06/04 Javascript
详解webpack打包vue时提取css
2017/05/26 Javascript
详解Vue.js之视图和数据的双向绑定(v-model)
2017/06/23 Javascript
利用jQuery异步上传文件的插件用法详解
2017/07/19 jQuery
Angular动态绑定样式及改变UI框架样式的方法小结
2018/09/03 Javascript
使用imba.io框架得到比 vue 快50倍的性能基准
2019/06/17 Javascript
简单了解微信小程序的目录结构
2019/07/01 Javascript
微信小程序日历插件代码实例
2019/12/04 Javascript
JavaScript实现像雪花一样的Hexaflake分形
2020/07/07 Javascript
[52:26]完美世界DOTA2联赛决赛 FTD vs Phoenix 第一场 11.08
2020/11/11 DOTA
Python实用日期时间处理方法汇总
2015/05/09 Python
利用python 更新ssh 远程代码 操作远程服务器的实现代码
2018/02/08 Python
python查找指定文件夹下所有文件并按修改时间倒序排列的方法
2018/10/21 Python
python实现PID算法及测试的例子
2019/08/08 Python
深入学习python多线程与GIL
2019/08/26 Python
django中的数据库迁移的实现
2020/03/16 Python
django 解决自定义序列化返回处理数据为null的问题
2020/05/20 Python
Python执行时间的几种计算方法
2020/07/31 Python
django前端页面下拉选择框默认值设置方式
2020/08/09 Python
html5+css3气泡组件的实现
2014/11/21 HTML / CSS
美国领先的在线旅游网站:Orbitz
2018/11/05 全球购物
自我鉴定200字
2013/10/28 职场文书
实习生单位鉴定意见
2013/12/04 职场文书
百年校庆节目主持词
2014/03/27 职场文书
银行委托书范本
2014/09/28 职场文书
酒店采购员岗位职责
2015/04/03 职场文书
个人职业生涯规划之自我评估篇
2019/09/03 职场文书
Python内置包对JSON文件数据进行编码和解码
2022/04/12 Python