点击下方“逆锋起笔”,公众号回复 编程资源

领取大佬们推荐的学习资料剧照:刺杀小说家

作者:三点水

https://lotabout.me/2021/Explicit-is-Better-than-implicit

“Explicit is better than implicit” 是 The Zen of Python 中的一句格言。长久以来都觉得挺在理,直到有天有人用这句话为基础,提出了一个我不甚赞同的观点,才发现从来就没有真正理解过它。

神奇的是在搜索过程中,发现讨论这句格言的并没有多少,不同的讨论中对 "explicit" 含义的理解差别也很大,最终发现最好的讨论来自 Elixer 社区:On ‘Explicit is better than Implicit’ 。本文尝试列举见过的一些观点,以及自己的理解。

Explicit 是什么含义?

Explicit 这个单词释义为:

stated clearly and in detail, leaving no room for confusion or doubt

“清楚详细地陈述,不容混淆或怀疑”。翻译成中文有“显式的”、“精密”、“不含糊”、“明确的”等多种翻译。在代码的语境下,什么样的代码才能称得上是 “explicit” 呢?网上看到了不同角度的观点。

一些观点

把代码显式写出来

显式地写出代码,也可以有多种理解方式,Making Games with Python and Pygame 中举了一个示例:

def getButtonClicked(x, y):if YELLOWRECT.collidepoint( (x, y) ):return YELLOWelif BLUERECT.collidepoint( (x, y) ):return BLUEelif REDRECT.collidepoint( (x, y) ):return REDelif GREENRECT.collidepoint( (x, y) ):return GREENreturn None # 这里显式地返回了 None

书中提到最后一行显式写 return None 能让读者更直接理解代码的用途。

思考:这个样例容易理解,也很赞同,但是如何推而广之呢?Explicit 在上面的例子中体现在哪呢?

我理解它的重点在于,当所有的 if 语句都不命中时,默认的行为是未知的,而显示写出的 return None 则清楚地描述了默认的情形,即使 Python 的默认行为发生变化,该方法的行为也不会发生变化。

要具体、要特化

这篇文章 明确表达了自己对“Explicit is Better than Implicit”的理解:

Being explicit means being concrete and specific instead of abstract and general. It also means not to hide the behavior of a function.

Explicit 意味着要具体、特化,不要抽象、通用。同时不要隐藏函数的行为。

对于要具体、特化,文章中举例如下:

# Explicit                               |  # Implicit
import requests                          |  from requests import *
r = requests.get("https://lotabout.me")  |  r = get("https://lotabout.me")

对这个例子也是比较认同的。但我认为重点不在于 requests.get 怎么好,而在于 import * 不好。因为这样的话 get 方法的来源就不明确了,容易混淆,需要靠猜。相对的,下面的代码我认为也是好的:

from requests import get
r = get("https://lotabout.me")

这里我的理解是,代码执行的逻辑,从溯源的角度上没有二义。如果用了 import *,同时两个模块中都有 get 方法,则容易混淆,不知道真正执行的是哪个方法。

不要隐藏函数行为

同样来自上面提到的文章 ,示例如下:

#Explicit
def read_csv(filename):# code for reading a csvdef read_json(filename):# code for reading a json#Implicit
def read(filename):# code for reading a csv or json# depending on the file extension

这个示例我不认同。从观念上,它与 OOP 中提到的封装的思想;从使用上,文件类型的判断的要求并没有消失,只是丢给用户自己实现了;进而从结果上,只要有多种文件类型存在,在某个层级上一定会有一个 read 方法的。

举例说,如果说不要隐藏函数的行为,那么我们在写 Web 服务的时候,在我们访问 DB 时,我们会希望直接处理 TCP 连接吗?Spring 框架选择隐藏这些行为,可以说是错误吗?

关键在于“预期”,与预期相符就是“Explicit”的,正如Elixer 社区的讨论 :“Don’t surprise me”。于是 Explicit 的要求演变成如何给用户正确的预期?我的回答是:良好命名,遵循 common sense,除此之外需要教育。

No Magic

Django 的 Design philosophies 中有如下描述:

Magic shouldn’t happen unless there’s a really good reason for it. Magic is worth using only if it creates a huge convenience unattainable in other ways, and it isn’t implemented in a way that confuses developers who are trying to learn how to use the feature.

这里指的是不要用复杂的语言特性(大家常把元编程称作 Magic)。

这个观点的持保留意见,我认为重点还是在于知识、背景是否匹配。例如当我熟悉 Decorator 时,就会觉得用 decorator 来指定一个 REST API 的路由很直观,很容易理解。但对于不熟悉的人可能就完全不能理解数据的路径(data path),不知道为什么一个注解是怎么真正完成 URL 到函数的绑定的。微信搜索公众号 逆锋起笔,关注后回复 编程资源,领取各种经典学习资料。

含义更直接

还有一些讨论会指向同一段逻辑的不同写法,例如SO 上的讨论 举的例子:

a = []# ① my understanding is that this is implicit
if not a:print("list is empty")# ② my understanding is that this is explicit
if len(a) == 0:print("list is empty")

这是一个“矛盾”的讨论,题主认为 ② 是 explicit,下面的回答则指出写成 ① 的方式能应对更多的情形,如 a 不是列表的情形。我能理解 ① 的作用,但同时也赞同题主的观点,从阅读的角度来说 ② 是更直接的。

还有 Elixer 社区的讨论 ,例子一方面说明什么是语义上的“直接”,也间接反驳“不要隐藏函数行为”的观点:

if (person.sex === 1 and person.children.length > 0) { ...do something... }if (person.isFemale() and person.hasChildren()) { ...do something... }if (person.isFemaleParent()) { ...do something... }

从阅读代码的角度,明显上最后一种最容易阅读,更符合语言习惯,不容易有歧义。

我所理解的 Explicit

上面我们看到,“Explicit is Better than Implicit”这句话本身就是 implicit 的,有很多歧义的理解。

我自己的总结是:Minimal Knowledge, No Surprise

对于阅读者/使用者而言,需要最少的知识去理解它,在我们隐藏复杂度的过程中,要保证函数/API/…行为符合预期,没有意外。

例如对于函数最后加上 return None 比不加要好,因为加上后,我们就不需要了解 Python 函数的默认返回值是什么。类似的,显式引用会更好:from requests import get,因为读者不需要去找 get 方法的来源,以及有重名时是哪个函数生效。

对于“不要隐藏函数行为”的做法,就有一定的反对意见。例如 read_csvread_json 是否优于 read 方法?我认为此时 No Surprise 很重要。对于 csv, json 等文件格式我认为 read 更优,因为根据扩展名判断类型是一个共识,并不会有 surprise 发生。而如果读取的是 HDFS 上的文件,由于很多文件保存时并不会按扩展名保存,我认为此时 read 就容易有 Surprise,因此是不合适的。

对于 Magic,如果做法不是 common sense,则需要我们额外学习 Magic 的含义,就是属于"Implicit" 的,此时用来是不用,就要看它能给我们带来多大的好处了。同样的还有语言中的语法糖,经常需要额外学习知识才能看懂/自己使用。

最后对于“含义更直接”,认为在 No Surprise 的前提下,越接近“共识”越好,因为需要更少的知识。

小结

关于 “Explicit is Better than Implicit?” 的理解,文章罗列了网上搜索的一些观点:

  • 把代码显式写出来,如显式加上 return None

  • 要具体、要特化,如显式 import:from requests import get

  • 不要隐藏函数行为,如实现 read_csvread_json 要好于只实现 read

  • No Magic,如非必要,不要使用元编程

  • 含义更直接,如用 len(a) == 0 判断列表为空而不是 not a

最后总结并说明了自己对 “explicit” 含义的理解:Minimal Knowledge, No Surprise

当然,我们会发现 Minimal Knowledge 或者说“共识”对于不同的群体,在不同上下文之下是不同的。这也是我们需要经验去理解,需要花时间去沟通的内容了。

近期热门文章推荐:

Deepin 深度系统更新(2021.02.03)发布
10 个“疯狂”的 Python 项目创意

Python 下载的 11 种姿势,一种比一种高级!

GitHub 上 25 个 Python 学习资源,墙裂推荐!

感谢创作者的好文

如何理解 Python 之禅:Explicit is better than implicit?相关推荐

  1. python import 原理-Python之禅-import this的实现

    学过Python的人想必都听过大名鼎鼎的Python之禅: The Zen of Python, by Tim Peters Beautiful is better than ugly. Explic ...

  2. Python之禅--给编程者的掏心窝子的话

    ➤01 Python之禅 下面是最简单的Python程序: import this 运行之后,便可以得到如下的输出了: The Zen of Python, by Tim Peters Python之 ...

  3. python之禅中文-Python之禅与翻译之美

    对于翻译,我没有什么发言权.我对翻译的了解大多来自思果先生的<翻译研究>和<翻译新究>这两本书.思果先生是著名的散文家.翻译家.说来惭愧,我还未能有幸拜读他的散文,不过只是这两 ...

  4. python禅怎么读_python学习——python之禅

    (一)python之禅: 在python中运行import this你会看到这样一段文字: The Zen of Python, by Tim Peters Beautiful is better t ...

  5. 【Python】Python之禅

    书上说:"Python程序员笃信代码可以编写得漂亮而优雅."小新虽然学习了 Python这门神奇的语言,但是自认为自己仍处于一个菜鸟的水平.所以呢,暑假也没闲着,把自己的Pytho ...

  6. 聊聊Python的一个彩蛋:Python之禅

    在Python的解释器中隐藏一个彩蛋,输入import this就会返回19条Python之禅,具体如下: >>>import this The Zen of Python, by ...

  7. Python|Python简介|安装Python解释器|运行|开发工具|Python之禅|turtle绘制五星红旗|绘制方块|绘制小猪佩奇|语言100课:学习(1)

    文章目录 源项目地址 初识Python Python简介 Python的历史 Python的优缺点 Python的应用领域 安装Python解释器 运行Python程序 确认Python的版本 编写P ...

  8. python之禅中文原文_python之禅 pdf

    python之禅(the zen of python) pdf电子版是一篇关于python编程的禅语心得,该版本已被翻译为中文,透彻易懂,具有一定的实践指导意义,需要的朋友欢迎在绿色资源网下载! Py ...

  9. 关于python的漫画_以漫画的形式写写Python之禅

    #漫画# 题记:我们经常在网络或本地的软件说明文档中,看到一些图形化的字符,看上去很抽象,很简洁,造型也相对明确,是一种计算机图形艺术(美化后的线条表现),因此,小编以为,这些图形化的字符,可以理解为 ...

  10. python之禅中文-「翻译」Python之禅

    Python之禅 Beautiful is better than ugly. 优美胜于丑陋. Explicit is better than implicit. 明了(显式)比隐晦(隐式)好. Si ...

最新文章

  1. 练习题 James and Dominoes
  2. FM之RKD_WORD_WRAP
  3. Flash,EEPROM区别
  4. 8.Vue 事件处理
  5. 《机器学习项目开发实战》送书活动结果公布
  6. java陷阱常见面试题_Java常见陷阱
  7. TensorFlow HOWTO 4.2 多层感知机回归(时间序列)
  8. 疑似华为Mate X 5G版入网 将支持两种组网方式
  9. Zookeeper3.4.10使用Curator
  10. 什么是HotSpot VM 深入理解Java虚拟机 JVM
  11. USB转RJ45串口调试线(console线)
  12. spring security+cas 单点登录示例(单点退出)
  13. 云优CMS批量翻译插件
  14. python爬虫国内外研究现状
  15. 用户价值分层——基于RFM模型的研究分析
  16. 【Python爬虫历程】使用Cookie来模拟登陆
  17. Lua游戏客户端框架通用功能模块
  18. Android Camera2对焦框和对焦
  19. 短信接口api发送-kewail
  20. 国产AI绘画海克斯科技——爱作画AIGC开放平台

热门文章

  1. java验证码问题(不区分大小写)升级版,输入不正确则一直输入
  2. pyodbc-操作SQLserver
  3. 对于接口得容错性测试
  4. Python判断素数
  5. 通过阿里云容器镜像服务下载谷歌gcr.io镜像
  6. 2011 北邮计算机研究生各组分数线
  7. c语言从键盘输入圆柱体的半径和高,c 写程序:输入圆柱的半径和高,计算并输出圆柱体的体积和表面积...
  8. Macbook二三事
  9. word 职称计算机考试大纲,全国职称计算机考试Word2003大纲
  10. VMware-Esxi7.0各个版本镜像文件iso下载链接