登录
首页大数据时代聊聊Python的一个彩蛋:Python之禅
聊聊Python的一个彩蛋:Python之禅
2020-07-15
收藏

相信大家在学习python肯定都听说过python之禅。python之禅到底是个什么东西,设计者为什么要这样设计?又有什么意义呢?看完下面的文章你就会明白了。

文章转载自:微信公众号 Python的乐趣

作者:一粒米饭

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

>>>import this
The Zen of Python, by Tim Peters

Beautiful is better than ugly.
Explicit is better than implicit.
Simple is better than complex.
Complex is better than complicated.
Flat is better than nested.
Sparse is better than dense.
Readability counts.
Special cases aren't special enough to break the rules.
Although practicality beats purity.
Errors should never pass silently.
Unless explicitly silenced.
In the face of ambiguity, refuse the temptation to guess.
There should be one-- and preferably only one --obvious way to do it.
Although that way may not be obvious at first unless you're Dutch.
Now is better than never.
Although never is often better than *right* now.
If the implementation is hard to explain, it's a bad idea.
If the implementation is easy to explain, it may be a good idea.
Namespaces are one honking great idea -- let's do more of those!

它的作者是 Tim Peter,这些设计理念开始是在Python邮件列表中发表,它包含了影响Python编程语言设计的19条软件编写原则。在最初及后来的一些版本中,一共包含20条,其中第20条是“这一条留空(...)请 Guido 来填写”。这留空的一条从未公布也可能并不存在。

其中从吉多·范罗苏姆的博客中可以了解到,最开始Python是他个人的一个实验项目(skunkworks)。为了加快Python发展,他采用了一些原则,其中包括省时规则(timesaving rules):

  1. 尽可能从其他地方借用想法,只有它有意义。
  2. “事情应该尽可能简单,但不要简单。” (来自爱因斯坦)
  3. 做好一件事情。(来自UNIX哲学)
  4. 不要太担心性能,可以在后面需要时进行优化。
  5. 不要与环境抗争,顺其自然。
  6. 不要尝试完美,因为“足够好”通常就是这样。
  7. (因此)有时可以偷工减料,尤其是后面可以完善的情况下。

还有除了省时规则以外的其他规则:

    1. Python实现不应局限于特定平台。可以运行某些功能并非总是可用的,但是核心部分应该在任何地方都可以使用。

    2. 不要用机器可以处理的细节来打扰用户。

    3. 支持和鼓励独立于平台的用户代码,但不要中断对平台功能或属性的访问(这与Java形成鲜明对比)。

    4. 大型复杂系统应具有多个扩展级别。这为经验丰富的用户(无论是否熟练)提供了最大的发挥空间。

    5. 错误不应致命。也就是说,只要虚拟机仍在运行,用户代码就应该能够从错误情况中恢复。

    6. 同时,错误不应静默地传递(后两项决定了在整个实现中使用异常)。

    7. 不应允许用户的Python代码错误导致Python解释器的不确定行为;核心错误绝不应该是由用户的错误引起的。

基于以上的哲学理念,Tim Peter整理了19条Python之禅并收录到Python增强建议(PEP 20)之中。

下面,再来简单说下这19条Python之禅的含义。

  • 优美优于丑陋(Beautiful is better than ugly)程序员经常为实现功能而快速编写代码,导致没有考虑可读性。但在这个看颜值的时代,优美的代码肯定更加优秀并且受人欢迎。看到糟糕的代码.gif
  • 明了优于隐晦(Explicit is better than implicit)这一条不言而喻的,应该让代码清晰可读,避免将代码的功能隐藏晦涩的代码中,使得别人需要在非常熟悉代码之后才能完全理解其功能。谁也不希望过一个月后再阅读自己的代码是下面的表情。阅读隐晦的代码.gif
  • 简单优于复杂, 复杂优于凌乱(Simple is better than complex, Complex is better than complicated)这两条提醒我们,构建任何事物都可以使用简单或复杂的技术来完成。对于一个简单的问题,例如建造一个鸟笼,一个简单的解决方案会更好。另一方面,制造火车发动机是一个复杂的问题,需要复杂的技术。即使可以使用鸟笼技术制造柴油火车引擎,最终也可能不是理想的解决方案。相对于复杂,简单一点更好,但要了解简单的局限性。
  • 扁平优于嵌套(Flat is better than nested)程序员喜欢将事物分门别类,尤其是包含子类的类别,这些子类又包含其他子类。但是,最好可以将代码仅放在一个顶层模块或类中,而不是将代码分散在多个子模块或子类中。如果制作需要导入import spam.eggs.bacon.ham.foo.bar之类的代码的程序包和模块,那么这代码就太复杂了。
  • 稀疏优于稠密(Sparse is better than dense)程序员通常喜欢将尽可能多的功能塞入尽可能少的代码中,例如像以下这样的单行代码:print('\n'.join("%i bytes = %i bits which has %i possible values." % (j, j*8, 256**j-1) for j in (1 << i for i in range(8))))虽然这样的代码能人自我感觉良好,但它会让尝试理解它的同事非常不爽。与密集的单行代码相比,分布在多行代码通常更易于阅读。
  • 可读性很重要!(Readability counts)自从1970年代以来一直使用C语言进行编程的人,strcmp()可能显然意味着“字符串比较”功能,但是现代计算机具有足够的内存来写出完整的函数名。不要从你的名字中删除元音,也不要写过于简洁的代码。代码的可读性和可维护性更重要,因此,清晰易读的代码比简洁的不清晰代码更为重要。
  • 即使实用比纯粹更优, 特例亦不可违背原则。(Special cases aren't special enough to break the rules, Although practicality beats purity)这两条是相互矛盾的。程序员有时撸起袖子就是干,代码能运行就行。这样的做法可能会导致一堆混乱的,无法维护的代码。另一方面,又会讲究各种设计模式,可复用性,比如Java编程语言尝试使所有代码适合其面向对象的范例,即使是最小的程序,也常常会导致大量样板代码。实际上,在这两种风格都不能走极端,要根据实际情况折中取舍。
  • 错误绝不能悄悄忽略, 除非它明确需要如此。(Errors should never pass silently, Unless explicitly silenced.)仅仅因为程序员经常忽略错误消息并不意味着程序应该停止发出错误消息。当函数返回错误代码而不引发异常时,可能会发生无提示的错误。但是,让程序快速失败并崩溃比使错误静默并继续运行程序更好。否则会不可避免地让后面发生的错误更加难以调试,因为它们与原始错误原因相去甚远。尽管你可以选择忽略程序所导致的错误,但是请确保这个错误是被你捕获的。
  • 面对不确定性,拒绝妄加猜测(In the face of ambiguity, refuse the temptation to guess)计算机不是魔术。如果代码无法正常工作,那是有原因的,只有谨慎,批判性的思维才能解决。不能盲目猜测、不加思考,随意的掩盖问题并不是真正地解决问题。
  • 任何问题应有一种,且最好只有一种,显而易见的解决方法(There should be one—and preferably only one—obvious way to do it)事实证明,用三种或四种不同的方式来编写可完成相同任务的代码是一把双刃剑:过于灵活的解决方法可以让人自由发挥。但如果都是随个人习惯实现,那会让整个项目的代码参差不齐,后期维护人员也会一头雾水。
  • 尽管这方法一开始并非如此直观,除非你是荷兰人(Although that way may not be obvious at first unless you're Dutch)这是一句玩笑话。吉多·范罗苏姆是Python的创建者和BDFL(独裁者)。但是,即使这样也不能阻止Python结合三种不同的格式化字符串的方式。
  • 做优于不做,然而不假思索还不如不做(Now is better than never, Although never is often better than right now)这两条告诉我们,挂起或陷入无限循环的代码显然是不好的。但是,几乎可以肯定的是,等待程序结束总比过早结束程序而导致错误结果要好。
  • 很难解释的,必然是坏方法。很好解释的,可能是好方法(If the implementation is hard to explain, it's a bad idea.If the implementation is easy to explain, it may be a good idea.)Python致力于简化程序员的工作,而不是适应计算机以使程序运行更快。程序不仅需要编写它的程序员可以理解,而且还需要其他维护代码的程序员可以理解。这两条提醒我们,如果“高性能”代码过于复杂以致程序员无法理解和调试,那么它就是不好的代码。反之,很容易向其他人解释程序的代码,并不意味着它不是不好的代码。编程是一件困难的事,程序员何苦为难程序员。
  • 命名空间是个绝妙的主意,我们应好好利用它(Namespaces are one honking great idea—let's do more of those)命名空间(以及全局和局部作用域)是防止一个模块或作用域中的名称与另一个模块或作用域中的名称冲突的关键。但也要记住,扁平比嵌套好,命名空间应该仅用于防止命名冲突,而不能添加不必要的分类。这些都是很好的设计哲学,每个有追求的Python程序员都应该谨记于心。

数据分析咨询请扫描二维码

客服在线
立即咨询