Pythonic到底是什么玩意儿?<?xml:namespace prefix = o ns = "urn:schemas-microsoft-com:office:office" />
作者:Martijn Faassen
译者:赖勇浩(http://blog.csdn.net/lanphaday)
原文地址:http://faassen.n--tree.net/blog/view/weblog/2005/08/06/0
注:Martijn 是 Zope 领域的专家,他为 Zope 系列产品做了许多开发工作,也开发了 lxml 等多个开源产品。你可以在这里了解一下他的信息http://www.zope.org/Members/faassen。这篇文章写于 2005 年,虽然有少部分内容(主要是例子)看起来已经有些过时,但即便是在今天,它的中心思想依然有极高的指导意义。
这是几个月前在 EuroPython 邮件列表(主要用来组织和计划 EuroPython 会议的邮件列表)出现的问题。这是一个非常有意思的问题,我看到这个词被无数次地使用,但鲜有人尝试解释它的含义。在这条线索之后,许多不同的人,包括我自己,都给出了自己的答案。现在我把我的答案放到博客上,并且润色了一下,希望它能对您有所增益。
Pythonnic 是一个模糊的概念,尽管没有“智能”或“生命”那么模糊,但当你尝试定义它们的时候,就像去抓住一条滑溜溜的泥鳅一样无从下手。可是虽然它们难以定义,然而并不意味着它们没用,因为事实上人们其实极善于利用混乱的定义。Pythonic 有点像“Python惯用法”的意味,现在让我们来聊聊它真正的含义。
随着时间的推移,Python语言不断演进,社区不断成长,涌现了许多关于如何正确地使用 Python 的 ideas。一方面 Python 语言推荐使用大量的惯用法来完成任务(“完成任务的唯一方法”),另一方面,社区不断演变的新的惯用法的又反过来影响了语言的进化,以更好地支持惯用法。比如新进入的字典的 .get() 方法,它把 has_key() 和元素存取两个操作组合为一个操作,从中可以看出这种进化。
惯用法往往不能直接从其它编程语言移植过来。如下文是实现对一个序列里的每个元素执行一个操作的 C 语言实现:
for (i=0; i < mylist_length; i++) {
do_something(mylist[i]);
}
直接的等效 Python 代码是这样的:
i = 0
while i < mylist_length:
do_something(mylist[i])
i += 1
这段代码能够完成工作,但并不 Pythonic,它并不是 Python 语言推荐的惯用法。让我们来改进一下。典型的 Python 惯用法是用内置的 range() 函数生成所有的序列下标:
for i in range(mylist_length):
do_something(mylist[i])
其实这种实现也并不 Pythonic,接下来大家看看语言推荐的实现方式,真正 Pythonic 实现:
for element in mylist:
do_something(element)
“如何直接传递或改变引用”是comp.lang.python 的“月经贴”,但在只有赋值(import、class、def 等语句也可视为赋值)的 Python 中这是不可能的。这种需求通常是因为想让函数返回多个值,用 C 或者许多其它编程语言的方法是给这个函数传入引用或指针:
void foo(int* a, float* b) {
*a = 3;
*b = 5.5;
}
...
int alpha;
int beta;
foo(&alpha, &beta);
在 Python 中可以用很囧很恶心的方法来实现:通过给函数传递序列参数来返回结果。写出来的代码可能像这样:
def foo(a, b):
a[0] = 3
b[0] = 5.5
alpha = [0]
beta = [0]
foo(alpha, beta)
alpha = alpha[0]
beta = beta[0]
显然这是毫无 Pythonic 可言的实现。Python 中让函数返回多个值的惯用法与此迥异,得益于元组和元组解包,它看起来也要漂亮得多:
def foo():
return 3, 5.5
alpha, beta = foo()
在经验老到的 Python 程序员看来,不够 Pythonic 的代码往往看起来古怪而且累赘,过于冗余也难以理解。因为它使用冗长的代码代替常见的、公认的、简短的惯用法来实现预期效果。更甚于此的是在语言支持正确的惯用法之后,非推荐的代码通常执行起来更慢。
Pythonic 就是以清晰、可读的惯用法应用Python 理念和数据结构。举个例子,应该多使用动态类型,在无必要之处引入静态类型就走向了另一端。另外也要避免使用经验丰富的 Python 程序员不熟悉的方式去完成任务(即遵循最小惊奇原则)。
Pythonic 一词也能够适用于底层的惯用法。一个 Pythonic 的库或框架能使程序员更加容易、更加自然地学会利用它来完成任务。如果用 Python 编写的库或框架迫使程序员编写累赘的或不推荐的代码,那么可以说它并不Pythonic。也许可能是为了使这个库更加方便、易懂,而没有应用 Python 的一些理念,如类等,那也是不 Pythonic 的。类定义应当尽可能地实现信息隐藏,虽然 Python 的许多操作都只作“宽松限制”(通常由程序员在属性的前面加上一个下划线来暗示这是私有成员),但也要做得像 Java 那样严格。
当然,当规模很大的时候,它是否 Pythonic 就极具争议性了。这里给出一些参考条款:如减少冗余,Python 的库与 APIs 都倾向于小型化和轻量化(相对于 java 程序库而言)。重量级的、API过于细化的的Python 库并不 Pythonic。比如 W<?xml:namespace prefix = st1 ns = "urn:schemas-microsoft-com:office:smarttags" /><chmetcnv w:st="on" tcsc="0" numbertype="1" negative="False" hasspace="False" sourcevalue="3" unitname="C">3C</chmetcnv> XML DOM API,尽管它的 Python 实现已经颇有时日,但大家并不认为它 Pythonic。有些人认为它是 Java 式的,虽然也有许多 Java 程序员认为并不如此。
一个Pythonic的框架不会对已经用惯用法完成的东西重复发明轮子,而且它也遵循常用的 Python 惯例。
当然,问题是构建框架时肯定会不可能避免地引入一些你不熟悉的模式和方法。Zope2 是我极为熟悉的一个框架,它也是一个引入了许多完成工作的特定的方法(如 Acquisition)的例子,这些方法往往什么地方都用不到,因此许多经验丰富的 Python 程序员认为它并不 Pythonic。
创建 Pythonic 的框架极其困难,什么理念更酷、更符合语言习惯对此毫无帮助,事实上这些年来优秀的 Python 代码的特性也在不断演化。比如现在认为像 generators、sets、unicode strings 和 datetime 之类的特性尤为 Pythonic。Zope2 的历史悠久,它从1997年开始开发,你不能把不够 Pythonic 归咎于它,甚至考虑到这么多年来它控制得如此之好,更应该感谢它。
关于 Pythonicness 的新趋势的一个例子是Python 的包和模块结构日益规范化。新的代码库如 Twisted、Zope3 和 PyPy 等或多或少都跟随了这样的潮流:
- 包和模块的命名采用小写,单数形式,而且短小。
- 包通常仅仅作为命名空间,如只包含空的 __init__.py 文件。
在我写库(如 lxml)的时候也遵循了这样的惯例。
因为更多人认为一个 Python 程序员容易学习的功能不那么强大的框架比一个需要大量时间来学习的强大系统更为 pythonic。所以有时我认为宣称软件不够 Pythonic 不公平,甚至可能会因此而掩盖了该软件积极的一面。
最后,作为什么是 Pythonic 的扩充材料,可以尝试一下在 Python 解释器里执行如下语句:
import this
分享到:
相关推荐
《PyPI官网下载 | Pythonic-0.12.tar.gz:深入理解Python库与云原生技术》 PyPI(Python Package Index),是Python社区官方的软件包仓库,提供了丰富的Python库供开发者下载和使用。资源"Pythonic-0.12.tar.gz"即...
Redisworks 0.4.0 Pythonic Redis 客户端为什么选择 Redisworks?惰性 Redis 查询动态类型易于使用您是否曾经使用过 PyRedis,并想知道为什么您必须一直考虑类型?您是否必须不断地将对象转换为字符串并反复转换,...
第14章 Pythonic与Python杂记.mp4
这个库的核心理念是提供一种“pythonic”的方式,即符合Python编程习惯的方式来操作数据库,使得开发人员在处理数据库任务时能更加高效、便捷。 在Python中,通常我们使用诸如SQLite、MySQL、PostgreSQL等数据库的...
fabric, 简单,Pythonic 远程执行和部署 fabric 是 python ( 2.5 -2.7 ) 库和命令行工具,用于简化应用程序部署或者系统管理任务的SSH使用。它为执行本地或者远程 shell 命令( 。正常或者通过 sudo ) 和上载/下载...
14.6_None|Pythonic与Python杂记|Python3.8入门_&_进阶_&_原生爬虫实战完全解读
刚刚获得的模式验证Pythonic模式是一个用于验证Python数据结构的库,例如从config / files,forms,外部服务或命令行解析获得的数据,这些数据是从JSON / YAML转换而来的(或者其他els Schema验证刚刚得到的Pythonic...
bidict-Pythonic双向映射数据结构
Pythonic-PHP-Code-Formatter, Pythonic PHP代码格式化程序只是为了好玩 Pythonic-PHP-Code-FormatterPythonic PHP代码格式化程序。仅供娱乐? 由 Twitter 激发。=========== =演示演示:http://www.94cb.com/Python
Pythonic and Reusable Code,python代码的可重用,更Pythonic 的技巧,好的代码,书中有将近30多个例子,让你了解更Pythonic代码写法,让你更了解python语言
"Python编程与实战 上有关项目实战的代码-Pythonic.zip"这个压缩包文件显然包含了用于教学或自我实践的Python项目代码,旨在帮助学习者更好地理解和运用Python语言的精华。Pythonic一词通常指的是遵循Python编程哲学...
pythonic拟合是什么样的? 好吧,有一个简单的测试。 如果我能为您提供一些示例代码,而不必使用任何其他字词来解释其功能,那将是pythonic。 from symfit import parameters , variables , Fit , Model import ...
简单的、Pythonic 的远程执行和部署。 欢迎来到 Fabric!Fabric 是一个高级 Python(2.7、3.4+)库,旨在通过 SSH 远程执行 shell 命令,从而产生有用的 Python 对象。它建立在Invoke(子进程命令执行和命令行功能)...
PyPika是一个强大的Python库,它允许开发者以一种非常Pythonic的方式构建SQL查询。这个工具的核心优势在于它保持了SQL的强大功能,同时提供了直观且易于理解的API,使得编写和操作SQL查询变得更为简单。PyPika的出现...
标题中的"PyPI 官网下载 | rkd.pythonic-2.4.1.dev144.tar.gz"表明这是一个从Python Package Index (PyPI) 官方网站获取的软件包,名为`rkd.pythonic`,版本号为2.4.1的开发版,具体是第144次迭代(dev144)。...
pyLookML允许您非常轻松地获取,解析和编程lookml。 它是在AWESOME lkml解析库之上构建的面向对象的元编程接口,您可以在此处查看: : 。 但是通过增加其json结构的便利性以及更高级的集成和面向对象的行为来扩展它...
Zipline, a Pythonic Algorithmic Trading Library
Zipline 是一个 Pythonic 算法交易库。它是一个用于回测的事件驱动系统。Zipline 目前在生产中用作 Quantopian 的回测和实时交易引擎——Quantopian是一个免费的、以社区为中心的托管平台,用于构建和执行交易策略。...