go 转 Python 的心智负担增加

10 天前
 yujianwjj

之前写 go ,go 调用函数的时候,有问题就是通过 返回值 有没有 err 来判断。心智负担很小,直接撸就行。

一个简单的案例,打开文件,然后 json 解析。 go 版本是

func TestA(t *testing.T) {
	fd, err := os.OpenFile("a.txt", os.O_RDWR, 0666)
	if err != nil {
		fmt.Println("打开文件失败", err)
	}
	defer fd.Close()

	var data map[string]string
	err = json.NewDecoder(fd).Decode(&data)
	if err != nil {
		fmt.Println("解析文件失败", err)
	}
	fmt.Println(data)
}

但是到 python 这边

f = open("a.json")
data = json.load(f)
f.close()

但是吧

  1. 如果文件不存在需要处理
  2. 文件存在,open() 执行异常了要处理
  3. json.load() 会不会异常?我跳转源码看 josn.load()源码也没看到他会返回哪些异常信息。

所以我写出这种代码

try:
	with open("a.json", "r") as f:
		data = json.load(f)
except Exception as e:
	print(e)

但是这样把多种异常合到一个 Exception 了,如果出现异常,你不知道是哪个函数调用出现的异常。所以就需要这样。

try:
	with open("a.json", "r") as f:
    	try:
			data = json.load(f)
    	except Exception as e:
			print(e)        
except Exception as e:
	print(e)

然后我发现,最大的问题就是,我每次调用一个外部函数的时候,TMD 根本不知道这个函数会不会异常,总不能每个函数调用都用 try/except 处理一下?

try:
	f1()
except Exception as e:
	print(e)
    
try:
	f2()
except Exception as e:
	print(e)
    
try:
	f3()
except Exception as e:
	print(e)

写 python 给我的感受就是,想写好一个健壮的程序,有很大的心智负担,我总是要考虑我调用的函数会不会有异常。

8052 次点击
所在节点    Python
96 条回复
Vegetable
9 天前
相比于 Go, Python 确实存在意想不到的报错这种情况。健壮的 Python 代码来自于经验,老练的 Python 使用者熟知常用库和方法会出现什么问题,哪里需要处理异常,并将异常融入自己设计的控制流。

所以 Python 写好并不容易,Go 的异常模式确实有其优势,虽然更多是被批评,但也看和谁比。
blockmin
9 天前
建议转别的语言,Python 就是一通莽,快就完事了,什么后果先不要管
sazima
9 天前
try:
...

except TypeRrror:
....
except AtributeError:
...
except ValueError:
....
idealhs
9 天前
try catch 都不会写,你这是 go 和 python 的问题?很怀疑你是不是只会 go
sky3hao9
9 天前
用惯了 GO, 说实话, 再看 Java, py, php 这些, 就跟看见屎粑粑一样
yingxiangyu
9 天前
logging.exception(e) 会把完整的调用栈都打印出来
qiuhang
9 天前
我看你不过是困在 go 里面还没出来罢了,说来说去你这不就可能存在 3 个异常吗?文件不存在,文件没法读取,json 解析异常,对应你 go 的逻辑,你这么写不就行了?

import json, os
filename = 'a.txt'
if not os.path.exists(filename):
raise Exception('文件不存在')

try:
with open(filename) as f:
json.load(f)
except Exception as e:
raise Exception(f'解析文件失败 {type(e)}')

或者你实在是要求细致到每一种异常,那你统一去 except 里面逐个处理不就行了

import json, os
filename = 'b.txt'
try:
with open(filename) as f:
json.load(f)
except Exception as e:
if isinstance(e, FileNotFoundError):
raise Exception('文件不存在')
elif isinstance(e, PermissionError):
raise Exception('...')
elif isinstance(e, json.decoder.JSONDecodeError):
raise Exception('...')
else:
raise Exception('...')
darksword21
9 天前
同感,所以每次想到那帮提案把 try cache 加到 go 里的人是不是脑子有什么大病

还有说“你可以截获不同的具体异常阿”

那么我怎么知道都有什么类型的异常呢?当前确实可以去源码里找,但是这和楼主说的“TMD 根本不知道这个函数会不会异常”是一个问题,可以说是心智负担+心智负担,相比之下明确返回 err 并在注释 doc 写上都可能有什么样的异常是最省心的
edisonwong
9 天前
前司有个项目,一个函数里不同阶段的 return 结构不一样,有时候是 string ,有时候是 tuple
现在只有快写脚本我是用 py 的,哈哈哈哈
lcvs
9 天前
你太严谨了,有问题就应该暴露问题,只用 try except 包住最外面那层就行了
NoOneNoBody
9 天前
脚本语言最大优势就是随时改,不用全部编译,尤其是调参脚本,谁会 ratio 改个 0.01 重新编译一遍啊
所以没必要的情况下不必写 try...except 容错,直接让它报错还更清晰(直接就显示哪一行出错)
try...except 更多是有两种方案时,此路不通换另一条,或者某些问题不重要,出错也可以 pass ,节省时间

初学的时候,确实对出错很敏感,但 python 写多几年就知道了,只要不是数据改动大,或者跑几小时的项目,报错不必紧张,及早发现比产出时报错好得多,不宜太早写 try
python 需要写容错的地方确实太多了,会的人知道 try...except 就是“掩饰”用的,产品真不适合给小白用户
redbule
9 天前
半斤八两吧,判断 err 和 try catch 我感觉都差不多,都挺影响读代码的
好的库应该尽量不抛出错误,因为你都处理不了还指望使用者处理? --《软件设计的哲学》
zonde306
9 天前
两者设计思路不一样,不能直接套用

在传统的异常处理里面,不需要考虑这么多东西,避免心智负担
异常这种东西,如果处理不了,那就不要处理,就直接让它抛出,交给上一层
上一层决定是放弃,还是重试,又或者不处理
不行就直接 crash

例如打开文件时文件不存在,文件不存在不好处理,直接 crash 损失更小,避免错误执行
yb2313
9 天前
费这功夫, ai 一秒给你全写完了, 感觉 py 的补全是很快的, 你完全可以不写任何异常, 最后直接让 ai 给你补上就行了
smlcgx
9 天前
都用 with 了没必要写 try 了吧,除非你想把异常捕捉打印出来,如果自己调试直接看报错就行了
henix
9 天前
我写 python 的时候大多数情况下都不用像 go 一样细致地处理异常
通常是不处理或者最外面一层 try catch 就完事
不知道抛什么异常,就等运行的时候报错了记录下来
hingle
9 天前
异常太多,只处理想处理的,其他的统一或全局处理或不管。

比如 Open ,会出现文件不存在、权限不足等各种错误,如何这些错误是业务需要,那就去处理。

“健壮的程序”,也只是相对的,在 go 的 json 序列化和反序列化里,甚至会 panic ,不可能每次都去 recover 。
chenqh
9 天前
我还是喜欢 python 这种异常,毕竟大部分异常我只能上抛,那为什么不让程序帮我上抛?
chenqh
9 天前
@DonaldVVV 居然还有这种东西?
chenqh
9 天前
我就不懂了?

python 里面你确实不知道发生了什么异常?难道 golang 里面你就知道什么 error 了吗?那不相当于 java 的 check error 了吗?

java 的 checkexception 不是已经证明是个 SB 了吗?

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

https://ex.noerr.eu.org/t/1140619

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

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

© 2021 V2EX