返回介绍

建议2:编写 Pythonic 代码

发布于 2024-01-30 22:19:09 字数 5155 浏览 0 评论 0 收藏 0

如何编写更加Pythonic的代码,与定义什么是Pythonic一样困难。在这里,只能给出一些经验之谈,希望对大家有所帮助。

(1)要避免劣化代码

与优化代码对应,劣化代码就是一开始写出来就是不合理的代码,比如不合适的变量命名等。通常有以下几个值得注意的地方:

1)避免只用大小写来区分不同的对象。如a是一个数值类型变量,A是String类型,虽然在编码过程中很容易区分二者的含义,但这样做毫无益处,它不会给其他阅读代码的人带来多少便利。

2)避免使用容易引起混淆的名称。容易引起混淆的名称的使用情形包括:重复使用已经存在于上下文中的变量名来表示不同的类型;误用了内建名称来表示其他含义的名称而使之在当前命名空间被屏蔽;没有构建新的数据类型的情况下使用类似于element、list、dict等作为变量名;使用o(字母O小写的形式,容易与数值0混淆)、l(字母L小写的形式,容易与数值1混淆)等作为变量名。因此推荐变量名与所要解决的问题域一致。有如下两个示例,示例二比示例一更好。

示例一:

>>> def funA(list,num):
...   for element in list:
...       if num==element:
...           return True
...       else:
...           pass
...

示例二:

>>> def find_num(searchList,num):
...   for listValue in searchList:
...       if num==listValue:
...           return True
...       else:
...           pass
...

3)不要害怕过长的变量名。为了使程序更容易理解和阅读,有的时候长变量名是必要的。不要为了少写几个字母而过分缩写。下例是一个用来保存用户信息的字典结构,变量名person_info比pi的可读性要强得多。

>>> person_info={'name':'Jon','IDCard':'200304','address':'Num203,Monday Road',
  'email':'test@gail.com'}

(2)深入认识Python有助于编写Pythonic代码

可以从以下几个方面进行着手:

全面掌握Python提供给我们的所有特性,包括语言特性和库特性。其中最好的学习方式应该是通读官方手册中的Language Reference和Library Reference。掌握了语言特性和库特性,以后许多“惯用法”自然而然就掌握了,写代码的时候,自然会使用常见的、公认的、简短的惯用法来实现预期效果,也使得代码显得尤为Pythonic。

随着Python的版本更新、时间的推移,Python语言不断演进,社区不断成长,还需要学习每个Python新版本提供的新特性,以及掌握它的变化趋势。从另一角度来看,一方面Python语言推荐使用大量的惯用法来完成任务(“完成任务的唯一方法”);另一方面,社区不断演变的新惯用法反过来又影响了语言的进化,以更好地支持惯用法。比如早年的Pythonista常用dict.has_key()方法来判断字典对象是否包含某个元素,但新版本的Python中提供了in操作符(支持多种容器类型)取代它。改变习惯的阻力很大,而克服这些阻力的唯一方法就是加深对Python的认识,因为在语言支持正确的惯用法之后,非推荐的代码通常执行起来更慢。所以说,不更新知识是不行的。

深入学习业界公认的比较Pythonic的代码,比如Flask、gevent和requests等。以requests这个通过HTTP(HTTPS)协议获取网络资源的程序库为例,要获取带有Basic Auth的网络资源时,代码如下:

import requests
r = requests.get('https://api.github.com', auth=('user', 'pass'))
print r.status_code
print r.headers['content-type']
# ------
# 200
# 'application/json'

而使用Python标准库httplib2时,代码就非常复杂,程序员需要了解相当多的关于HTTP协议和Basic Auth的知识才能编程。

import urllib2gh_url = 'https://api.github.com'
req = urllib2.Request(gh_url)
password_manager = urllib2.HTTPPasswordMgrWithDefaultRealm()
password_manager.add_password(None, gh_url, 'user', 'pass')
auth_manager = urllib2.HTTPBasicAuthHandler(password_manager)
opener = urllib2.build_opener(auth_manager)
urllib2.install_opener(opener)
handler = urllib2.urlopen(req)
print handler.getcode()
print handler.headers.getheader('content-type')
# ------
# 200
# 'application/json'

看,使用一个Pythonic的程序库可以简化很多工作量!那么深入学习理解类似requests的高质量程序库带给我们的收获应该完全可以预期:一定是非常大的!

最后,除了修炼内功外,也可以尝试利用工具达到事半功倍的效果。所以接下来介绍风格检查程序PEP8。其实一开始PEP8是一篇关于Python编码风格的指南,它提出了保持代码一致性的细节要求。它至少包括了对代码布局、注释、命名规范等方面的要求,在代码中遵循这些原则,有利于编写Pythonic的代码。比如,对代码的换行,不好的风格如下:

if foo == 'blah': do_blah_thing()
do_one(); do_two(); do_three()

而Pythonic的风格则是这样的:

if foo == 'blah':
  do_blah_thing()
do_one()
do_two()
do_three()

如果要“人肉”检查代码是否符合PEP8规范,则比较困难,而且容易跟同僚引发争论。所以Johann C. Rocholl开发了一个应用程序来进行检测,就是应用程序PEP8。当然,它是使用Python开发的,安装它非常容易。

$ pip install -U pep8

在自己的shell中执行这一命令就可以安装成功了(首先需要安装pip)。然后即可简单地用它检测一下自己的代码。

$ pep8 --first optparse.py
optparse.py:69:11: E401 multiple imports on one line
optparse.py:77:1: E302 expected 2 blank lines, found 1
optparse.py:88:5: E301 expected 1 blank line, found 0
optparse.py:222:34: W602 deprecated form of raising exception
optparse.py:347:31: E211 whitespace before '('
optparse.py:357:17: E201 whitespace after '{'
optparse.py:472:29: E221 multiple spaces before operator
optparse.py:544:21: W601 .has_key() is deprecated, use 'in'

可以看到上面有许多错误和警告,然后我们按图索骥逐一修复它们就可以了。如果嫌这种报表不够细致,可以考虑使用--show-source参数让PEP8显示每一个错误和警告对应的代码。

$ pep8 --show-source --show-pep8 testsuite/E40.py
testsuite/E40.py:2:10: E401 multiple imports on one line
import os, sys
     ^
  Imports should usually be on separate lines.
  Okay: import os\nimport sys
  E401: import sys, os

看,它甚至可以给出“正确”的写法!除了针对某一个源代码文件以外,它还可以直接检测一个项目的质量,并通过直观的报表给出报告。

$ pep8 --statistics -qq Python-2.5/Lib
232   E201 whitespace after '['
599   E202 whitespace before ')'
631   E203 whitespace before ','
842   E211 whitespace before '('
2531  E221 multiple spaces before operator
4473  E301 expected 1 blank line, found 0
4006  E302 expected 2 blank lines, found 1
165   E303 too many blank lines (4)
325   E401 multiple imports on one line
3615  E501 line too long (82 characters)
612   W601 .has_key() is deprecated, use 'in'
1188  W602 deprecated form of raising exception

PEP8有优秀的插件架构,可以方便地实现特定风格的检测(例如,有些公司、团队会定义自己的风格);它生成的报告易于处理,可以很方便地与编辑器集成(例如,实现点击出错信息跳转到相应代码行)。所以这是一个非常有用的工具,它可以提升你对Pythonic的认识,达到编写高质量代码的目的。

PEP8不是唯一的编程规范,事实上,有些公司制定的编程规范也非常有参考意义,比如Google Python Style Guide。同样,PEP8也不是唯一的风格检测程序,类似的应用还有Pychecker、Pylint、Pyflakes等。其中,Pychecker是Google Python Style Guide推荐的工具;Pylint因可以非常方便地通过编辑配置文件实现公司或团队的风格检测而受到许多人的青睐;Pyflakes则因为易于集成到vim中,所以使用的人也非常多。

其实Pythonic的代码,往往是放弃自我风格的代码,而要有“放弃自我风格”的觉悟,是非常困难、非常痛苦的。要突破这种瓶颈,完成自我蜕变,除了需要付出许多精力去学习外,参考更好的书籍进行辅助也是相当有帮助的。目前市面上针对编写“高质量”的Python程序的方法的书籍并不多,本书应是一本比较好的参考资料。作为作者,我们也真心希望自己的一点点经验分享能够对读者有所帮助。

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。
列表为空,暂无数据
    我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
    原文