python开发的程序_腾讯8年Python开发经验程序员写给初学者的总结

开始测试:

Shell

; html-script: false ](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来返回样本数据而不是真正的进行调用。

Python

; html-script: false ]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"

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

Shell

; html-script: false ](test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ nosetests test_mock.py

Ran 1 test in 10.001s

OK

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

Python

; html-script: false ]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"

好吧,让我们再试一次:

Shell

; html-script: false ](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(),然后你会在你的程序运行时,获得一个很好的交互式提示。它每次执行程序的一行并且检查变量。

15243603_201811211057435p0QB.jpg

腾讯在职8年Python开发经验的程序员写给初学者的总结,希望有用

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

Python

; html-script: false ]a = 1

b = 2

a = b

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

Shell

; html-script: false ](test)jhaddad@jons-mac-pro ~VIRTUAL_ENV/src$ python -m trace --trace tracing.py 1 ?

--- modulename: tracing, funcname:

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来追踪性能问题。它可以创建函数调用时间和次数的图表。

15243603_201811211057436QUXC.jpg

腾讯在职8年Python开发经验的程序员写给初学者的总结,希望有用

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

Gevent

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

Python

; html-script: false ]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:

Python

; html-script: false ](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获取,这是非常有用的。我并不是很喜欢回调函数,所以这一抽象对我来说效果很好。

结论

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

上文内容不用于商业目的,如涉及知识产权问题,请权利人联系博为峰小编(021-64471599-8017),我们将立即处理。

22/2<12

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值