Python代码的编程习惯主要参考PEP8:
https://www.python.org/dev/peps/pep-0008/
里面主要包括如每行代码长度不超过79,函数间空一行等。
这些只要平时多加注意,理解起来不是问题。其实除了PEP8指定的这些代码编写习惯外,还有一种与代码健壮性息息相关的编程风格,今天重点介绍这方面的编程习惯。
为了提升代码的健壮性,我们要做防御性编程,Python中的try
和except
就是主要用来做这个:
d = {'a': 1, 'b': [1, 2, 3]}
try:
val = d['c']
except KeyError:
print('key not existence')
try
块中代码是受保护的,如果键不存在,except
捕获到KeyError
异常,并处理这个异常信息。
而下面的代码,一旦从字典中获取不存在的键,如果没有任何try
保护,则程序直接中断在这里,表现出来的现象就是app直接挂掉或闪退,这显然非常不友好。
d = {'a': 1, 'b': [1, 2, 3]}
val = d['c']
再举一个try
和except
使用的例子,如果目录已存在则触发OSError
异常,并通过except
捕获到然后在块里面做一些异常处理逻辑。
import os
try:
os.makedirs(path)
except OSError as exception:
if exception.errno != errno.EEXIST:
raise # PermissionError 等异常
else:
# path 目录已存在
以上这种使用try
和except
的防御性编程风格,在Python中有一个比较抽象的名字:EAFP
它的全称为:
Easier to Ask for Forgiveness than Permission.
没必要纠结上面这句话的哲学含义。
知道在编程方面的指代意义就行:首先相信程序会正确执行,然后如果出错了我们再处理错误。
使用try
和except
这种防御风格,优点明显,try里只写我们的业务逻辑,except里写异常处理逻辑,几乎无多余代码,Python指南里也提倡使用这种风格。
但是任何事物都有两面性,这种写法也不例外。那么,EAFP防御风格有何问题呢?它主要会带来一些我们不想出现的副作用。
举一个例子,如下try块里的逻辑:出现某种情况修改磁盘的csv文件里的某个值,这些逻辑都顺利完成,但是走到下面这句代码时程序出现异常,进而被except
捕获,然后做一些异常处理:
try:
if condition:
revise_csv() # 已经污染csv文件
do_something() # 触发异常
except Exception:
handle_exception()
由于try块里的逻辑分为两步执行,它们不是一个原子操作,所以首先修改了csv文件,但是do_something
却出现异常,导致污染csv文件。
其实,除了以上EAFP防御性编程风格外,还有一种编程风格与它截然不同,它虽然能很好的解决EAFP的副作用,但是缺点更加明显,所以Python中不太提倡大量的使用此种风格。
明天我们再介绍另一种编程风格:LBYL
原创不易,欢迎点赞支持。