gitbook/Python核心技术与实战/docs/108661.md
2022-09-03 22:05:03 +08:00

85 lines
6.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 32 | 答疑(三):如何选择合适的异常处理方式?
你好,我是景霄。
不知不觉中,我们又一起完成了第三大章规范篇的学习。我非常高兴看到很多同学一直在坚持积极地学习,并且留下了很多高质量的留言,值得我们互相思考交流。也有一些同学反复推敲,指出了文章中一些表达不严谨或是不当的地方,我也表示十分感谢。
大部分留言,我都在相对应的文章中回复过了。而一些手机上不方便回复,或是很有价值很典型的问题,我专门摘录了出来,作为今天的答疑内容,集中回复。
## 问题一:应该使用哪种异常处理方式?
![](https://static001.geekbang.org/resource/image/c7/42/c766890764672c7c924092d9dfd0c942.png)
第一个问题是code2同学的疑惑。下面这两种处理的风格,哪一种风格更有效、更优雅?
* 第一种,在代码中对数据进行检测,并直接处理与抛出异常。
* 第二种,在异常处理代码中进行处理。
其实,第一种方法,可以翻译成下面的“if…elif…”语句:
```
if [condition1]:
raise Exception1('exception 1')
elif [condition2]:
raise Exception2('exception 2')
...
```
而第二种方法,则对应着下面异常处理的代码:
```
try:
...
except Exception as e:
...
```
这两种方法很大的一个区别是,第一种方法一旦抛出异常,那么程序就会终止;而在第二种方法中,如果抛出异常,会被程序捕获(catch),程序还会继续运行。这也是我们选择这两种方法的重要依据。当然,在实际工作中,到底使用哪一种方法,还是取决于具体的场景。
比方说,一个模块的功能是对输入进行检测,如果输入不合法,则弹出对话框进行提示,并终止程序。那么,这种情况下,使用第一种方法更加合理。
但是,如果换成一个产品的服务器端,它需要应对各种可能发生的情况,以保证服务器不崩溃。比如在连接数据库时,如果网络异常,无法连接,那就需要捕获(catch)这个异常(exception),进行记录,并同时保证其他功能不受影响。这种情况下,我们通常会选择第二种方式。
## 问题二:先写出能跑起来的代码,后期再优化可以吗?
![](https://static001.geekbang.org/resource/image/d5/b0/d5efddbe80757e61e33596ce41440bb0.png)
第二个问题,夜路破晓同学提到了很多程序员传授的“经验之谈”,即先写出能跑起来的代码,后期再优化。很明显,这种认知是错误的。我们从一开始写代码时,就必须对功能和规范这两者双管齐下。
代码功能完整和规范完整的优先级是不分先后的,应该是同时进行的。如果你一开始只注重代码的功能完整,而不关注其质量、规范,那么规范问题很容易越积越多。这样就会导致产品的bug越来越多,相应的代码库越发难以维护,到最后不得已只能推倒重来。
我在Facebook工作时就遇到过这样的情况,参与过类似的项目。当时,某些功能模块因为赶时间,code review很宽松,代码写得很不规范,留下了隐患。时间一长,bug越来越多,legacy越来越多。到最后,万分无奈的情况下,我们几个工程师专门立项,花了三个多月时间,重写了这一模块的代码,才解决了这个问题。
## 问题三:代码中写多少注释才合适?
![](https://static001.geekbang.org/resource/image/f2/71/f22b2ec07051b244ed4a852189745671.png)
第三个问题,小侠龙旋风同学留言说,自己的同事要求代码中有70%的注释,这显然有点过了。但是反过来说,如果你的代码中没有注释或者注释很少,仅凭规范的变量名肯定是远远不够的。
通常来说,我们会在类的开头、函数的开头或者是某一个功能块的开头加上一段描述性的注释,来说明这段代码的功能,并指明所有的输入和输出。除此之外,我们也要求在一些比较tricky的代码上方加上注释,帮助阅读者理解代码的含义。
总的来说,代码中到底需要有多少注释,其实并没有一个统一的要求,还是要根据代码量和代码的复杂度来决定。不过,我们平常书写时,只要满足这样的规范就可以了。
另外,必须提醒一点,如果在写好之后修改了代码,那么代码对应的注释一定也要做出相应的修改,不然很容易造成“文不对题”的现象,给别人也给你自己带来困扰。
## 问题四:项目的API文档重要吗?
![](https://static001.geekbang.org/resource/image/fc/c5/fc59ac08ab33764afa439056e75acac5.png)
第四个问题,是未来已来同学的留言。他提到了项目的API文档的问题,这一点说得非常好,在这里我也简单介绍一下。
我在专栏中主要讲的是代码的规范问题,但很多情况下,光有规范的代码还是远远不够的。因为一个系统,一个产品,甚至一个功能模块的代码,都有可能非常复杂。少则几千行,动辄几十万行,尤其是对于刚加入的新人来说,在ramp up阶段光看代码可能就是一个噩梦了。
因此,在这方面做得比较规范的公司,通常也会要求书写文档。项目的文档,主要是对相应的系统、产品或是功能模块做一个概述,有助于后人理解。以一个service为例,其对应的文档通常会包括下面几部分:
* 第一点,系统的概述,包括各个组成部分以及工作流程的介绍;
* 第二点,每个组成部分的具体介绍,包括必要性、设计原理等等;
* 第三点,系统的performance,包括latency等等参数;
* 第四点主要说明如何对系统的各个部分进行修改,主要给出相应的code pointer及对应的测试方案。
这些内容,也希望屏幕前的你能够牢记。
今天我主要回答这些问题,同时也欢迎你继续在留言区写下疑问和感想,我会持续不断地解答。希望每一次的留言和答疑,都能给你带来新的收获和价值。