用 try...except...提高代码的稳定性,是否是好习惯?

2020-05-29 19:25:08 +08:00
 Leon6868

把每个可能出错的东西都套上 try...except,这样有什么坏处吗?
比如,是否会影响代码的执行效率?

8525 次点击
所在节点    Python
48 条回复
Leigg
2020-05-29 19:28:18 +08:00
看情况吧,有些异常是必须暴露的
Leigg
2020-05-29 19:28:40 +08:00
except 也要加上具体的 err
whi147
2020-05-29 19:29:19 +08:00
你好,是的。
xulolololololo
2020-05-29 19:29:38 +08:00
不要随便 catch,必须做一些真实的假设,如果和假设不符合,就是 bug 应该暴露出来被修复
MeteorCat
2020-05-29 19:29:54 +08:00
我同意看情况来使用,确实有的异常是必要的
Leon6868
2020-05-29 19:30:05 +08:00
@Leigg 没加上具体的 error 会有什么坏处吗,比如影响可读性?
qile1
2020-05-29 19:54:03 +08:00
@Leon6868 python 里面强调不要这样使用
try
execpt E*** as e:
print ( e )
我反正是就这样用了,有些异常很难想到,不这样处理后台服务类程序可能直接退出,所以为了不出现程序自动退出情况,我选择使用大量 try 来规避,对性能影响不太大,之前好像看到过有人做测试,使用 try 好像影响不大
Immortal
2020-05-29 20:00:47 +08:00
很多人吐槽和嘲笑的 golang err 处理 反而我看来是成语健壮稳定的保证 传统的 try catch 自我安慰的成分挺高
Immortal
2020-05-29 20:01:12 +08:00
@Immortal 成语->程序
xujinkai
2020-05-29 20:02:54 +08:00
给用户使用的程序,我会在最外层加以防程序莫名崩了。给程序员的库,要是用的太随意,会导致本该报错的地方莫名出现 bug 还不好找。
hdbzsgm
2020-05-29 20:07:11 +08:00
@Immortal #8 这边建议了解一下 java
cozof
2020-05-29 20:07:51 +08:00
python 没有全局捕获异常的方式么,一般写个中间件全局捕获异常记录日志,在配置文件做个开关,生产环境打开,开发环境关闭,直接抛异常。
Jirajine
2020-05-29 20:08:36 +08:00
@Immortal 去掉异常控制流把错误由返回值统一处理确实是进步,但 go 的简陋导致错误处理太 verbose 了,rust 那种包装在一个 Result 枚举里面就方便很多,预计 go2 也会增加一些语法糖来简化。
superrichman
2020-05-29 20:29:28 +08:00
@cozof 可以用装饰器实现
GeruzoniAnsasu
2020-05-29 20:48:44 +08:00
哎。。。
为什么看起来好多人都不明白异常处理是干啥用的
建议学习一下 gcc 异常处理的实现方式感受一下


从程序执行流本身来看,异常的意义在于回滚调用栈

回滚调用栈。

如果你不确定是不是该上异常处理,那就判断一下此时是不是想把调用栈回滚到某个状态前。一个用异常处理的绝佳例子是 visitor 设计模式,当递归 visit 到某一个节点发生错误时,显然把 error code 穿过层层递归跟等于 nil 的 result 一起传回来是个非常蠢的做法(你甚至得给每一种节点类型的 visit 函数都写一遍 if err return ! shit !)


从业务逻辑上来看,异常处理机制是用来统一处理某封闭模块在各个阶段产生的同类错误用的

比如游戏读图,在每个关卡我要读不同的地图文件,文件读上来以后要解析数据结构,有可能读图失败,有可能结构不对,出错了以后我想让游戏回退到选图界面,那我肯定没理由在写游戏逻辑的地方还判断 loadNextStage()成功了没有,抛出异常可以让更上层的逻辑来处理同时打断游戏逻辑,其实还是对应回调用栈回滚的本质



再回头看为什么指南不建议你写 try except print 是不是理解一些了
reus
2020-05-29 21:21:30 +08:00
这个就是纸尿裤一样的东西,有些人要用,但会控制大小便的人不需要。
Narcissu5
2020-05-29 21:33:20 +08:00
一个基本原则就是只 catch 你能处理的异常,捕获异常之后应该进行处理然后程序继续运行。如果是无法处理的异常,比方连不上数据库了,则使用 let it crash 的原则,让整个过程失败并回滚,阻止异常进一步扩散
hakono
2020-05-29 22:03:08 +08:00
建议楼主了解下 Let it crash 的思想,这个思想对理解异常处理很有帮助

出错了?出错了就出错了呗,崩了就崩了呗,崩了的时候你至少知道系统出错了。总好过你用 try exception 乱包一气,然后系统出错了还不明不白继续执行下去,等你注意到的时候可能已经过了好久,数据都因此乱七八糟了要好。

当然这里不是说你不该用 try,只是什么 try exception 的话对系统来说是个灾难
ruyu
2020-05-29 22:15:24 +08:00
个人认为要尽可能地暴露问题, 但是要防止问题扩大化
akazure
2020-05-29 22:28:18 +08:00
try final 应该更有意义吧

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/676803

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX