在开始讨论Python社区所采用的具体标准或是由其余人推荐的建议以前,考虑一些整体原则很是重要。python
请记住可读性标准的目标是提高可读性。这些规则存在的目的就是为了帮助人读写代码,而不是相反。算法
本小节讨论你所需记住的一些原则。数据库
人们很容易倾向相信某时所完成的工做在将来不须要添加一部分或对其维护。这是因为很难预料到将来的需求,以及低估本身形成Bug的倾向。然而,所写代码不多不被修改一直存在。编程
若是你假设本身所写代码会“一劳永逸”的无需以后进行阅读、调试或修补,那么你就会很是容易陷入忽视其余可读性原则的境地,这仅仅是由于你相信“此次并不重要”。app
所以,保持对本身感受所写代码无需维护的直觉的不信任才是上策。稳赚不赔的办法是赌本身将会再次见到本身写的代码。即便你不维护,那也须要其余人维护。框架
一致性的两个方面分别为:内部一致性和外部一致性。ide
不管是从代码风格和代码结构层面来说,代码都要尽可能知足内部一致性。不管是哪一种格式化规则,代码风格都要贯穿项目保持一致。代码结构的一致性也就是一样类型的代码放到一块儿。这样项目容易把控。函数
代 码还应该保持外部一致性。项目与代码的结构与其余人保持一致,若是一个新来的开发人员打开你的项目,你不该该让他的反应是:“我历来没见过像这样的东 西”。社区指导原则很重要,由于这就是开发人员加入到你的项目预期所见。相似的,以及相同的缘由,请认真看待在使用特定框架时完成任务以及组织代码所采用 的标准。工具
存在论(Ontology)的主要意思就是“关于存在的研究”。在哲学上(在该领域这个词很经常使用)存在论是关于现实与存在本质的研究,是形而上学的子集。网站
而对于写软件程序来讲,存在论指的是关注不一样“事物”在程序中如何存在。你如何将概念转化为在数据库中表示?亦或是用类结构表示?
这类问题最终影响你编写或组织代码的方式。是否使用继承或是组合来组织两个类之间的关系?数据库中用哪一个表完成这项功能或是这个列属于谁?
这些建议最终归结为“在写代码以前先思考”。尤为是思考程序但愿实现的目标,以及程序之间如何交互。程序是一个对象与数据交互的世界。那么,它们之间协做所需遵循的规则是什么?
当编写代码时,请考虑随着时间重复使用的值将会变动的状况。该值是否被用于多个模块或函数中?若是必要,须要花费多大代价修改它?
一样的原则适用于函数。你是否在程序中有大量的重复的代码?若是这些重复代码行数较多,能够考虑将其抽象到一个函数中,若是出现修改代码的需求,则更容易管理。
另外一方面,对于该原则不要过犹不及。并非全部值都须要在模块中定义为常量(这么作会损害可读性和可维护性)。请明智判断,不断问这样一个问题:“若是须要变动该代码,变动该代码的全部位置所须要的成本是多少”?
代码是一个故事。它是所发生故事的说明,在用户与程序交互过程当中,从开始到结束。程序从某一点开始(可能带有一些输入),沿着一系列“选择本身的冒险故事”步骤到达终点,并结束(极可能带有一些输出结果)。
采用的注释风格能够是每一些行代码以前就添加一段注释,用于解释代码的功能。若是代码是一个故事,那么注释就是故事的解释与旁白。
若是叙事式注释作的很好,读者就能够经过阅读注释了解故事,从而解析代码(例如,当尝试解决问题或维护代码时),而后能够从零开始快速了解所需维护的代码,这样就能够专一于代码自己所表明的意义。
叙事式注释还能够帮助解释代码意图。它能够回答这样的问题:“写这段代码的人但愿完成的目标是什么?”偶尔,还能够帮助回答问题:“为何以这种方式完成工做”?这些问题是在你阅读代码时很天然会问的,为这些问题提供答案将会帮助了解这些内容。
所以,注释用于解释代码中不显而易见或复杂部分的原理。若是使用了有点复杂的算法,请考虑将指向解释模式文章的连接以及其余使用示例加入注释。
编 写可维护代码最重要的原则通俗来说就是奥卡姆剃刀原则:最简单的解决方案一般是最好的。在他的“Python之禅”博文 (https://www.python.org/dev/peps/pep-0020/),该页面是编程格言的集合(例如,在Python控制台中输入 “import this”就能够看到这篇),Tim Peters也包括了相似下面这句“若是你没法向人描述你的方案,那确定不是一个好方案”。
上述原则在代码如何运行与代码外观层面都生效。当提到代码运行时,简单的系统更加容易维护。实现的简单化意味着更少引入复杂的BUG,哪些维护你代码的人(包括你本身)更容易凭直觉理解代码所表明的含义,并在不踩坑的前提下为程序增长代码。
至 于代码的外观,请记住,尽量使得阅读代码就好像是在了解代码所作工做的故事,而不是为了解析词汇。词汇是手段,而故事才是最终目的。写一条诸如“不要使 用三元运算符”很容易。然而仅仅是遵循这些规则(虽然有价值)并非代码明晰的充分条件。请专一以尽量简洁的方式编写和组织代码
Python社区大部分遵循所谓的PEP 8(https://www.python.org/
dev/peps/pep-0008/)指导原则,由Guido van Rossum(Python之父)编写并被包括Python标准库中的大多数主流Python项目采用。
PEP 8的广泛性是其强大的缘由之一。该标准被大多数社区项目采纳,所以你能够预计大多数你遇到的Python代码都遵循该标准。当你以这种方式编写代码时,代码会更加容易阅读,也更容易编写。
大多数PEP 8中的指导原则都很简单明了。部分重点以下:
l 使用4个空格缩进。不要使用制表符(\t)。
l 变量应该使用下划线链接,不使用骆驼式命名风格(使用my_var而不是myVar)。类名称以字母开头就是骆驼式命名风格(例如:MyClass)。
l 若是一个变量的用处是:“仅内部使用”,在变量名称以前加上下划线。
l 在运算符先后加上单空格(例如,x + y,不是x+y),也包含赋值运算符(z = 3而不是z=3),只有在关键字参数状况下不适用,在这种状况下,空格能够省略。
l 在列表和字典中省略没必要要的括号,(例如: [1, 1, 2, 3, 5],而不是[ 1, 1, 2, 3, 5 ])。
请阅读Python代码风格指南得到更多示例以及有关这些规则的更多讨论。
请记住,在Python中,若是在一个函数或类中第一个语句是一个字符串,该字符串会自动赋值给一个特殊的“_doc_”变量,该变量在调用Help(和一些其余的类)时会被使用。
PEP 8 规定文档字符串(该名称能够被望文生义)是必须的。
"""Do X, Y, and Z, then return the result."""
该句子与做为描述的文档字符串的对比:
"""Does X, Y, and Z, then returns the result."""
若是文档字符串是一行,那么须要在类或函数体以前加空行。若是文档字符串有多行,则将结束的双引号单独放一行。
空行用于逻辑分块。
PEP8规定“最高级”的类和函数定义之间有两个空行。
class A(object): pass class B(object): pass
代码清单1.
PEP 8还规定除了最高级以外,类和函数的定义以一个空行分隔。
class C(object): def foo(self): pass def bar(self): pass
代码清单2.
在函数或其余代码段中使用单空行分隔逻辑段是合理的。请考虑在逻辑段以前使用注释解释代码段的做用。
Python容许绝对路径导入和相对路径导入。在Python2中,解释器会尝试相对导入,若是找不到路径,而后再尝试使用绝对导入。
在Python 3中,使用特殊语法标记相对当如----以(.)开头----“正常”的导入方式只会尝试相对路径。Python 3的语法在Python 2.6之后版本可使用。除此以外你可使用—“_future_”关闭隐式相对路径导入。
若是可能,尽可能使用绝对路径导入。若是不得不使用相对路径,请使用显式导入风格。若是你为Python 2.6或 2.7编写代码,请考虑选择Python 3中的显式风格。
当导入模块时,每一个模块单独占一行。
import os import sys
代码清单3
然而,若是你从同一个模块中导入多个名称,固然能够将这些名称分组到一行中。
from datetime import date, datetime, timedelta
代码清单4
除此以外,虽然PEP 8并无强制要求,考虑以包来源的方式将导入分组。对于每一组,按照字母表顺序排序。
另外,在导入时,请不要忘了使用as关键字给导入的内容起别名。
from foo.bar import really_long_name as name
代码清单5
这使得你能够简化被频繁使用的长名称或不规范命名的名称。
当导入被频繁使用且原始名称不管何种缘由不规范时,别名就颇有价值了。
另外一方面,请记住当你这么作时,你会在你的模块中掩盖了原始名称,若是不必使用别名,这会使得代码变得不清晰。不管是使用何种工具,要作到具体状况,具体分析。
正如以前所提到的,变量名称使用下划线链接,而不要使用骆驼代码风格(例如,my_val而不是myVal)。除此以外,起一个具备描述性的名称一样重要。
一般状况下使用很是短的变量名称并不合适,虽然某些状况下这么作也能接受,好比在循环中的变量(例如,for k in mydict_item())。
避免命名的函数名称与Python语言中的经常使用名称重复,就算是解释器容许也不行。不管在任何状况下,都不要命名某个对象为sum或print。相似的,避免list或dict之类的名称。
如 果你必需要命名一个与Python类型与关键字同名的变量,惯例是在变量名称以后加下划线;相比修更名称的拼写来讲,这么作更加可取。例如,若是你将一个 类做为参数传递给一个函数,那么参数名称应该为class_,而不是klass(一个例外是静态方法,按照惯例使用cls做为第一个参数)。
注释应该使用英语写完整的句子(译者注:固然在国内这点值得商榷),放在相关的代码以前。正确使用首字母大写和语法,以及保证拼写正确。
同时,保证注释最新。若是代码变动,那么注释可能也须要随之变动。你应该不但愿注释与代码表示的意思相反,这很容易致使混淆。
模块可能包含一个注释头,一般由版本控制系统生成,其中包含文件版本的信息。这使得发现文件被修改变得容易,尤为是在将模块分发给别人使用时。
Python代码风格最有争议(也是最常被拒绝使用的)的方面是对行长度的限制。PEP 8要求行长度不超过79个字符,文档字符串不超过72个字符。
该规则让不少开发人员感到沮丧,这些开发人员认为咱们生活在一个27寸宽屏显示器的时代。GitHub是一个很是流行共享代码的网站,所使用的窗口宽度是120个字符。
而该规则的支持者指出不少人依然使用窄屏或80字符长度的终端,甚至仅仅是将代码窗口的宽度设置为小于屏幕宽度。
争论很难有一个结果。总之,不管是遵循79字符宽度的标准或是更宽的标准,你应该按照项目标准的规范编码。当行长度过长时,你应该知道如何处理代码。
使用圆括号是封装单行长代码的最佳方式,以下所示:
if (really_long_identifier_that_maybe_should_be_shorter and other_really_long_identifier_that_maybe_should_be_shorter): do_something()
代码清单6
只要可能,使用该方法,而不是在换行符以前使用 \字符。注意在使用诸如and之类的操做符时,尽量将其置于换行符以前。
封装函数调用也是能够的。PEP 8列出了许多可接受的方式完成封装。通常规则是使得同级别行缩进保持一致。
really_long_function_name( categories=[ x.y.COMMON_PHRASES, x.y.FONT_PREVIEW_PHRASES, ], phrase='The quick brown fox jumped over the lazy dogs.', )
代码清单7
当在函数调用、列表或字典中分行时,在行结尾部分添加逗号。
大多数时候,一年后阅读你代码的人就是你本身。记忆并不像一开始时那么好用。在编写代码时没有留心代码的可读性与可维护性天然会使得代码难以阅读和维护。
通观本书,你学会了如何使用Python中多种模块、类与结构。当须要决定如何解决问题时,请记住调试代码比写代码更有技术含量。
所以,以代码尽量简洁和可读为目标。一年后的你将会感谢本身。固然,你的同事以及下属也会感谢你。
------本篇结选自本人翻译的书《Python 高级编程》, 清华大学出版社-------------------------------------------------------------------------------------------------