Python 之禅“显式胜于隐式”

Posted

技术标签:

【中文标题】Python 之禅“显式胜于隐式”【英文标题】:Zen of Python 'Explicit is better than implicit' 【发布时间】:2021-01-12 03:27:41 【问题描述】:

我不确定这是一个固执己见的问题,还是我误解了 Python 上下文中“隐式”和“显式”的真正含义。

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")

我正在尝试遵循 Python 的禅宗规则,但我很想知道这是否适用于这种情况,或者我是否过度思考?感谢我能得到的任何指导。

【问题讨论】:

为什么是a?为什么list?错字? 是的,错字。为错误道歉。 确实有点奇怪。将其更改为 == 0。在这种情况下,听起来“len(a) == 0”比“not a”更明确,但它们都被认为是明确的? 它只是隐含的意思是你需要知道一个列表的“真实性”,但这在 Python 中是一个非常成熟的概念。 if not a 明确检查 a 是否为假(在这种情况下为空)。 if len(a)==0 明确检查 a 的长度是否等于 0。 【参考方案1】:

这两个语句具有非常不同的语义。请记住,Python 是动态类型的。

对于a = [] 的情况,not alen(a) == 0 是等价的。一个有效的替代方法可能是检查not len(a)。在某些情况下,您甚至可能想通过 a == [] 来检查空虚和列表。

但是a 可以是任何东西。例如,a = None。检查not a 很好,将返回True。但是len(a) == 0 一点都不好。相反,您将获得TypeError: object of type 'NoneType' has no len()。这是一个完全有效的选项,但 if 语句做的事情非常不同,你必须选择你想要的。

(几乎)Python 中的所有东西都有__bool__ 方法,但并非所有东西都有__len__。您必须根据情况决定使用哪一个。需要考虑的事项是:

您是否已经验证过a 是否是一个序列? 您需要吗? 您介意您的 if 语句在非序列上崩溃吗? 您想将其他 falsy 对象当作空列表来处理吗?

请记住,让代码看起来漂亮是正确完成工作的第二位。

【讨论】:

感谢您的解释!似乎我关注的是可读性,而不是正在发生的事情的潜在含义和最初的预期目的。【参考方案2】:

试着想想:

if not a:
    ...

简写为:

if len(a) == 0:
    ...

我认为这不是 Python 的“显式”优于“隐式”的禅宗规则的一个很好的例子。这样做主要是因为可读性。并不是说第二个不好,另一个很好。只是第一个比较熟练。如果有人了解 Python 中列表的布尔性质,我认为您会发现第一个在 Python 中更具可读性和可读性。

【讨论】:

一个不比另一个熟练。他们的意思不同。例如,一种仅适用于序列,另一种则不适用。了解差异是技能的用武之地。否则,这将是一个基于意见的问题。 好点,但我想这是一个见仁见智的问题。我想指出,这更多是为了可读性,而不是显式与隐式的演示。 我指出存在语义差异。在这一点上,可读性排在第二位。 我认为这很公平。 作为 Python 的新生,可读性对我来说非常重要。当然,这是假设代码首先按预期工作:P【参考方案3】:

虽然这个帖子有一些时间,但我想提供一个观点。在动态语言中,我的偏好是始终描述变量的预期类型和目标,以便提供更多目的理解。然后尽可能使用语言的知识来简洁并增加可读性(在python中,空列表的布尔结果为假)。因此代码:

    lst_colours = [] 
    
    if not lst_colours: 
      print("list is empty")

更好地传达含义是使用变量进行非常具体的检查。

    lst_colours = []
    b_is_list_empty = not lst_colours

    if b_is_list_empty: 
      print("list is empty")

检查列表是否为空将是在代码库中多次执行的常见操作。因此,在单独的文件辅助函数库中更好地进行此类操作。从而隔离常见检查,减少代码重复。

    lst_colours = []

    if b_is_list_empty(lst_colours): 
      print("list is empty")


    def b_is_list_empty (lst):
        ......

最重要的是,尽可能多地添加含义,有一个商定的公司标准来选择如何处理简单的事情,比如变量命名和隐式/显式代码选择。

【讨论】:

以上是关于Python 之禅“显式胜于隐式”的主要内容,如果未能解决你的问题,请参考以下文章

Python之禅

python之禅

Python之禅,亦是人生之禅

Python之禅

Python之禅

Python之禅