简单的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 Json模块中dumps、loads、dump、load函数介绍
May 15 Python
python判断设备是否联网的方法
Jun 29 Python
Python/ArcPy遍历指定目录中的MDB文件方法
Oct 27 Python
Python设计模式之装饰模式实例详解
Jan 21 Python
python assert的用处示例详解
Apr 01 Python
python3对拉勾数据进行可视化分析的方法详解
Apr 03 Python
计算机二级python学习教程(2) python语言基本语法元素
May 16 Python
Django之使用celery和NGINX生成静态页面实现性能优化
Oct 08 Python
ipad上运行python的方法步骤
Oct 12 Python
Django中文件上传和文件访问微项目的方法
Apr 27 Python
浅谈keras中的Merge层(实现层的相加、相减、相乘实例)
May 23 Python
Python TypeError: ‘float‘ object is not subscriptable错误解决
Dec 24 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
《星际争霸重制版》兵种对比图鉴
2020/03/02 星际争霸
php 显示指定路径下的图片
2009/10/29 PHP
浅析php数据类型转换
2014/01/09 PHP
php中current、next与reset函数用法实例
2014/11/17 PHP
PHP之预定义接口详解
2015/07/29 PHP
PHP中大括号'{}'用法实例总结
2017/02/08 PHP
实例讲解YII2中多表关联的使用方法
2017/07/21 PHP
PDO操作MySQL的基础教程(推荐)
2017/08/18 PHP
奇妙的js
2007/09/24 Javascript
JavaScript高级程序设计 扩展--关于动态原型
2010/11/09 Javascript
JavaScript 变量作用域分析
2011/07/04 Javascript
IE下支持文本框和密码框placeholder效果的JQuery插件分享
2015/01/31 Javascript
jquery滚动特效集锦
2015/06/03 Javascript
javascript实现下拉提示选择框
2015/12/29 Javascript
使用BootStrap和Metroui设计的metro风格微网站或手机app界面
2016/10/21 Javascript
H5实现中奖记录逐行滚动切换效果
2017/03/13 Javascript
在使用JSON格式处理数据时应该注意的问题小结
2017/05/20 Javascript
Windows下快速搭建NodeJS本地服务器的步骤
2017/08/09 NodeJs
浅谈Node.js爬虫之网页请求模块
2018/01/11 Javascript
js+canvas实现验证码功能
2020/09/21 Javascript
Element input树型下拉框的实现代码
2018/12/21 Javascript
跟老齐学Python之使用Python查询更新数据库
2014/11/25 Python
Python字符串格式化的方法(两种)
2017/09/19 Python
Python 3实战爬虫之爬取京东图书的图片详解
2017/10/09 Python
关于python写入文件自动换行的问题
2018/06/23 Python
python爬取淘宝商品销量信息
2018/11/16 Python
Jupyter Notebook安装及使用方法解析
2020/11/12 Python
用Python自动清理系统垃圾的实现
2021/01/18 Python
Pyecharts 中Geo函数常用参数的用法说明
2021/02/01 Python
python数据抓取3种方法总结
2021/02/07 Python
德国在线购买葡萄酒网站:Geile Weine
2019/09/24 全球购物
几个常见的软件测试问题
2016/09/07 面试题
信息管理专业学生自荐信格式
2013/09/22 职场文书
清洁工表扬信
2014/01/08 职场文书
学生会个人总结范文
2015/02/15 职场文书
一次项目中Thinkphp绕过禁用函数的实战记录
2021/11/17 PHP