Python 的 if 如果判断语句过于冗长,有书写技巧不?

2022-01-20 17:54:09 +08:00
 pppguest3962

如:

if (a or b) and (c.get('d') == 1 or e.get('f') == 1) and (not g or not h) and (type(i) == list or type(j) == list):  

如果 a,b,c,d...j (而且还不止)的正式变量名,均在 8 个字符以上,这种条件判断阅读和书写上一行都超屏了, if 如果下面嵌套 if ,也不好看,if 就不能逐个子条件折一下行么?

3894 次点击
所在节点    Python
24 条回复
pppguest3962
2022-01-20 17:55:39 +08:00
如果 if 嵌套,那么真正的执行内容缩进到那一节,也超屏了
lasuar
2022-01-20 17:57:28 +08:00
```
and_set1 = (a or b) and (c.get('d') == 1 or e.get('f') == 1)
and_set2 = (not g or not h) and (type(i) == list or type(j) == list)

if and_set1 and and_set2:
```
pppguest3962
2022-01-20 17:58:43 +08:00
@lasuar 妙,多弄几个新变量。
Pilippa
2022-01-20 17:59:37 +08:00
长度不是问题,
条件应该可读清晰才是重要的
以下纯粹举例

is_qualified = a or b
is_allowed = c.get('d') == 1 or e.get('f') == 1
is_valid_type = isinstance(i, list) or isinstance(j, list)

if is_qualified and is_allowed and is_valid_type:
# do something here...
pppguest3962
2022-01-20 18:00:08 +08:00
还能多几行码量增加了工作量,妙
shawnbluce
2022-01-20 18:01:58 +08:00
@pppguest3962 #3 不过这种写法要注意一个问题。如果写成原来那种很长一串的话,不论是 and 还是 or 都有可能提前遇到判定短路从而跳过后面的条件,例如 a or b or c or d or e 的情况下如果 a 直接就 True 了那么后面的判断就不需要了,性能上要比多弄几个变量更好一些
shawnbluce
2022-01-20 18:02:38 +08:00
@shawnbluce #6 不是说前面这种写法就不好,只是单纯提出一种看法
cclin
2022-01-20 18:04:23 +08:00
if (
(a or b)
and (c.get("d") == 1 or e.get("f") == 1)
and (not g or not h)
and (type(i) == list or type(j) == list)
):
pass

使用 black 格式化一下就好
gadfly3173
2022-01-20 18:04:33 +08:00
不如把判断结果抽成几个变量,这也太长了
ClericPy
2022-01-20 18:15:57 +08:00
忘了哪本书提到过, if 里面逻辑太复杂, 把相关逻辑抽取成一个完整逻辑的函数, 保证可读性. 当然如果计算非常简单提取成变量也没问题, 函数是为了逻辑短路避免无用计算
imycc
2022-01-20 18:17:12 +08:00
折行呗,大概长这样,也不用什么括号

```
if cond_a \
and cond_b \
and cond_c:
pass
```
imycc
2022-01-20 18:18:36 +08:00
缩进被删了有点麻。if 折行之后下一行是两个缩进的距离,为了 if 里面一个缩进的语句区分开来
rwecho
2022-01-20 18:19:42 +08:00
pep8 会给加换行的
imn1
2022-01-20 18:41:44 +08:00
conditions =[
(a or b),
(c.get('d') == 1 or e.get('f') == 1),
(not g or not h),
(type(i) == list or type(j) == list)
]
if all(conditions):

all 和 any 是支持短路的

或者
写成闭包函数(也无需传参),每行短路判断 --> if not xxx: return False
chevalier
2022-01-20 18:47:13 +08:00
这种 if 很显然,你的程序设计有问题,逻辑划分和封装得不合理

这一个 if 的圈复杂度已经是 13 ,先不说队友得死多少脑细胞才能看明白和维护,光你的单测得写多少用例才能覆盖?
lasuar
2022-01-20 18:47:42 +08:00
@imn1 这种更妙!
cmdOptionKana
2022-01-20 18:56:10 +08:00
@chevalier 确实,这么复杂的 if 语句,逻辑没划分清楚的可能性极大。
karloku
2022-01-20 19:47:56 +08:00
如果优化不了条件的话, 可以设计成能提前进行 return/continue/break 的执行方式

当然最好是想办法优化一下判断条件, 这么长的判断式可读性很差
ilylx2008
2022-01-20 19:56:02 +08:00
Python: 时间花在排版上
msg7086
2022-01-20 20:20:29 +08:00
@shawnbluce #6
是不是可以把变量改写成 lambda 延迟执行,这样就支持短路了吧。

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

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

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

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

© 2021 V2EX