笔者:风起怨江南 出处:https://blog.csdn.net/JackMengJin 笔者原创,文章转载需注明,如果喜欢请点赞+关注,感谢支持!
导读:Python之禅和PEP 8规范,值得所有使用Pyhton语言编程的coder熟知和掌握。
目录
Python之禅和PEP8规范
一、Python之禅
Python之禅是什么?
Python之禅的由来
PEP 8规范
PEP 8 定义
主动换行
隐式连接
URL写一行
return里不写括号
参数与变量对齐
四个空格缩进
顶级定义空两行
方法定义空一行
括号内保持紧凑
符号后添加空格
不要对齐注释
文档注释
复杂操作需要追加注释
显式类继承
避免使用+或+=符号
多行字符串用三重双引号
contextlib.closing()关闭
TODO注释
每个导入独占一行
if可以独占一行
单下划线开头
双下划线开头
同一模块管理相关类和函数
main
if __name__ == '__main__'
79字符限制
空序列判断
==不要和布尔值比较
Python之禅就是Python编程和设计的指导原则,由Tim Peter写的《The Zen of Python》。
如何看到Python之禅?在Python交互式解释器中输 入import this
,
就会显示Tim Peters的 The Zen of python。
Beautiful is better than ugly.
# 优美胜于丑陋(Python以编写优美的代码为目标)
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.
# 不要包容所有错误,除非你确定需要这样做(精准地捕获异常,不写except:pass风格的代码)
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 之父(这里的Dutch是指Guido)
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!
# 命名空间是一种绝妙的理念,我们应当多加利用(倡导与号召)
关于Python之禅的由来,这还要从一个名叫 Perl 的编程语言说起。
Perl,一种功能丰富的计算机程序语言,运行在超过100种计算机平台上,适用广泛,从大型机到便携设备,从快速原型创建到大规模可扩展开发。 Perl借取了C、sed、awk、shell脚本语言以及很多其他程序语言的特性,其中最重要的特性是它内部集成了正则表达式的功能,以及巨大的第三方代码库CPAN。简而言之,Perl像C一样强大,像awk、sed等脚本描述语言一样方便,被Perl语言爱好者称之为“一种拥有各种语言功能的梦幻脚本语言”、“Unix中的王牌工具”。 Perl一般被称为“实用报表提取语言”(Practical Extraction and Report Language),你也可能看到“perl”,所有的字母都是小写的。一般,“Perl”,有大写的P,是指语言本身,而“perl”,小写的p,是指程序运行的解释器。
编程语言 Perl 曾在互联网领域长期占据着统治地位,早期的大多数交互式网站使用的都是 Perl 脚本。Perl 社区奉为座右铭的一句话就是 “解决问题的办法有多个” !(是不是很像刚开始学编程的我们,总是喜欢尝试各种实现方法?)
由于这种语言固有的灵活性使得大多数问题都有很多不同的解决之道,一度深受大家的喜爱。但缺点来了,在开发项目期间,这种灵活性是可以接受的,但过于强调灵活性会导致大型项目难以维护。
其实不难理解,项目维护得通过研究代码搞清楚当时开发项目的人是怎么实现的,只有搞清楚后才能对代码进行维护,但 Perl 的灵活性使得问题有不同的解决之道,在维护阶段就十分的让人头疼。
正是鉴于 Perl 语言遇到的问题,经验丰富的程序员在编写 Python 代码时就有了避繁就简的理念。最终在某一天由一个叫 Tim Peters 的人撰写了出来,即 “Python之禅”。它并非出自 Python 创始人之手,但已被官方认可为编程原则。
以上便是Python之禅的由来。而说到Python之禅就不得不说起Python的PEP8规范。
PEP 是 Python Enhancement Proposal(Python 增强建议书)的缩写,8 代表的是 Python 代码的样式指南。
关于PEP8规范其实很早就已经开始注意了:pycharm。用pycharm来编写Python代码时,可以语法高亮,智能提示。每次编写代码如果有出现不符合PEP 8规范的话,pycharm就会提示。
有一点需要注意,不要为了遵守PEP约定而破坏兼容性。跟公司的项目组统一规范,如果有明确的规范要求还是跟着公司的保持同步。下面对PEP 8规范中进行简单的梳理。
主动换行指的是将较长、较多的参数换行处理,79字符分界线换行。建议将编辑器的自动换行关掉。这里以 webdriver.Chrome() 里初始化参数举例:
def __init__(self, executable_path="chromedriver", port=0,
options=None, service_args=None,
desired_capabilities=None, service_log_path=None,
chrome_options=None, keep_alive=True):
合理使用括号实现隐式连接。在if判断后表面较长的表达式用括号去实现隐式连接。或者将较长的字符串用括号连接。
st = ("这是一个非常长非常长非常长非常长非常长"
"非常长非常长非常长非常长非常长非常长非常长非常长的字符串")
注释中,如果出现URL,请把URL写在一行。
# 注释里的url地址:https://cn.bing.com/search?q=pep+8&qs=AS&pq=pep&sk=AS2&sc=8-3&cvid=BC59EBBF77B048A18A2D32E1143D9D04&FORM=QBRE&sp=3
不要再返回值或条件语句中使用括号,除非需要数字计算或行连接。
return x, y
函数参数与起始变量对齐。
student = stu_info(var_one, var_two,
var_three, var_four)
传参的时候可以用四个空格表示缩进。
student = {
long_dict_key:
long_dict_value,
...
}
在前面代码没有缩进时表示顶级定义,顶级定义之间空两行。
class Demo1(object):
pass
class Demo2(object):
pass
类中的方法定义中间空一行。
class Demo1(object):
def __init__(self, name):
self.name = name
def name(self):
self.name = None
括号里不要有空格,括号里应保持紧凑,调用时同理。
def sut_info(name, y=None):
return name, y
在逗号冒号分号后面添加空格。
不要用空格垂直对齐注释,但同时也要和公司保持一致。
函数的文档注释第一行为简单的功能解释,空一行后写函数的详细解释,再空一行写参数,再空一行写返回值。
def demo(case, row):
"""一般为祈使句,简单的说明下函数作用
空一行
详细的写下函数作用...
空一行
Arg:
对每个参数进行详细解释。
空一行
Returns:
对返回值功能描写。
空一行
写一个返回值的例子。
空一行。
写上可能出现的异常情况。
"""
文档注释有不同的风格,比如requests库和selenium库,selenium库的注释更贴近于PEP8,requests库为Pycharm注释风格。
类的注释类似函数,不同的是在类的注释中,需要写清楚类属性的作用。一个函数只写一个文档注释。
"""
Allows you to set the address of the remote devtools instance
that the ChromeDriver instance will try to connect to during an
active wait.
:Args:
- value: address of remote devtools instance if any (hostname[:port])
"""
"""
Requests HTTP Library
~~~~~~~~~~~~~~~~~~~~~
Requests is an HTTP library, written in Python, for human beings. Basic GET
usage:
>>> import requests
>>> r = requests.get('https://www.python.org')
>>> r.status_code
200
>>> 'Python is a programming language' in r.content
True
... or POST:
>>> payload = dict(key1='value1', key2='value2')
>>> r = requests.post('http://httpbin.org/post', data=payload)
>>> print(r.text)
{
...
"form": {
"key2": "value2",
"key1": "value1"
},
...
}
The other HTTP methods are supported - see `requests.api`. Full documentation
is at .
:copyright: (c) 2017 by Kenneth Reitz.
:license: Apache 2.0, see LICENSE for more details.
"""
在代码块中,对于复杂的操作,应该在操作开始前写上若干行注释,对于不是一目了然的代码,应该在其行尾添加注释,而不要描述代码。
代码块注释用多行描述,而不要写成注释字符串。
# 这是代码注释,不要用""" 注释字符串 """
# 这是代码注释,不要用""" 注释字符串 """
# 这是代码注释,不要用""" 注释字符串 """
如果一个类不继承自其他类,就显式的从obkect继承,嵌套类也一样。在python3中可以省略,python2中不行。
class DemoClass(object):
由于字符串是不可变的,每次循环中用+和+=操作符来累加字符串,其实是调用了CPU,不断的创建字符串,进行赋值操作,影响性能。这样做会创建不必要的临时对象,并且导致二次方而不是线性的运行时间。
建议将每个子串加入列表.append方法,然后在循环结束后用.join连接列表,这种方法不会产生临时变量。
当项目中使用单引号来引用字符串时,才可能会使用三重单引号表示多行字符串,绝大多是用"""。
类文件对象的方法,对于不支持使用"with"语句的类似文件的对象,使用contextlib.closing():
import contextlib
with contextlib.closing(urllib.urlopen("http://www.python.org/")) as front_page:
for line in front_page:
print line
有'__enter__','__exit__'两个对象的才支持with语句,可以通过dir()内置函数去查看是否存在这两个对象。
['_CHUNK_SIZE', '__class__', '__del__', '__delattr__', '__dict__', '__dir__', '__doc__', '__enter__', '__eq__', '__exit__', '__format__', '__ge__', '__getattribute__', '__getstate__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__lt__', '__ne__', '__new__', '__next__', '__reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '_checkClosed', '_checkReadable', '_checkSeekable', '_checkWritable', '_finalizing', 'buffer', 'close', 'closed', 'detach', 'encoding', 'errors', 'fileno', 'flush', 'isatty', 'line_buffering', 'mode', 'name', 'newlines', 'read', 'readable', 'readline', 'readlines', 'reconfigure', 'seek', 'seekable', 'tell', 'truncate', 'writable', 'write', 'write_through', 'writelines']
为临时代码使用TODO注释,TODO后接括号写上email地址或其他标识符,表示未来会去做这件事。统一格式。
# TOOD(Jack): Change this to use relations.
每个导入占一行,导入顺序,标准库导入->第三方库导入->应用程序指定导入。不推荐连续Import导入。
import sys
import requests
from selenium import webdriver
可以from ... import xxx, xxxx 连续导入。
在没有else的情况下,if语句可以独占一行。
if 1: print(1)
用单下划线(_)开头,表示模块变量或函数是protected的(使用import * from时不会包含)。
_name = 'Jack'
用双下划线(__)开头的实例变量或方法表示类内私有。
__file_name = 'python_study'
单下划线开头和双下划线开头有什么区别?单下划线表示protected,双下划线__表示private。
单下划线_开头的表示被保护的,在别的py文件中无法导入使用该对象。
双下划线__在类中表示私有的,在别的py文件中无法使用该类中双下划线定义的对象。
当不想让别人访问和使用变量时,内部逻辑处理,并不对外开放或内部逻辑要使用的变量,都可以设置为私有的或者保护的。
将相关的类和顶级函数放在同一模块,不像Java,没必要限制一个类一个模块。
将主体功能(main functionality)写在main()函数中,防止在导入该py模块时调用了该模块的主功能。
def main():
pass
所有模块是可以导入的,所以在执行主程序前必须总是检查if __name__ == '__main__':。
if __name__ == '__main__':
main()
所有行数限制为79字符,一行不要超过79字符。
直接用if 加序列或if not 加序列,不要用if len(seq) == 0。
lst = ['a', 'b', 'c']
if lst:
print('hello world!')
不要用==去和布尔值做比较,if 变量即可,不要用if 变量 == True或if 变量 is True。
if 1:
print("这是Pthon学习22,PEP8规范!")
以上便是《Python学习22:Python之禅和PEP 8规范》的所有内容,原创不易,如果喜欢请点赞和关注,谢谢大家的支持!
想获得免费的学习资料请添加微信公众号——风起怨江南。