V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐学习书目
Learn Python the Hard Way
Python Sites
PyPI - Python Package Index
http://diveintopython.org/toc/index.html
Pocoo
值得关注的项目
PyPy
Celery
Jinja2
Read the Docs
gevent
pyenv
virtualenv
Stackless Python
Beautiful Soup
结巴中文分词
Green Unicorn
Sentry
Shovel
Pyflakes
pytest
Python 编程
pep8 Checker
Styles
PEP 8
Google Python Style Guide
Code Style from The Hitchhiker's Guide
pppguest3962
V2EX  ›  Python

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

  •  
  •   pppguest3962 · 164 天前 · 3386 次点击
    这是一个创建于 164 天前的主题,其中的信息可能已经有所发展或是发生改变。

    如:

    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 就不能逐个子条件折一下行么?

    24 条回复    2022-01-27 14:15:48 +08:00
    pppguest3962
        1
    pppguest3962  
    OP
       164 天前
    如果 if 嵌套,那么真正的执行内容缩进到那一节,也超屏了
    lasuar
        2
    lasuar  
       164 天前
    ```
    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
        3
    pppguest3962  
    OP
       164 天前
    @lasuar 妙,多弄几个新变量。
    Pilippa
        4
    Pilippa  
       164 天前
    长度不是问题,
    条件应该可读清晰才是重要的
    以下纯粹举例

    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
        5
    pppguest3962  
    OP
       164 天前
    还能多几行码量增加了工作量,妙
    shawnbluce
        6
    shawnbluce  
       164 天前
    @pppguest3962 #3 不过这种写法要注意一个问题。如果写成原来那种很长一串的话,不论是 and 还是 or 都有可能提前遇到判定短路从而跳过后面的条件,例如 a or b or c or d or e 的情况下如果 a 直接就 True 了那么后面的判断就不需要了,性能上要比多弄几个变量更好一些
    shawnbluce
        7
    shawnbluce  
       164 天前
    @shawnbluce #6 不是说前面这种写法就不好,只是单纯提出一种看法
    cclin
        8
    cclin  
       164 天前 via Android   ❤️ 1
    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
        9
    gadfly3173  
       164 天前
    不如把判断结果抽成几个变量,这也太长了
    ClericPy
        10
    ClericPy  
       164 天前
    忘了哪本书提到过, if 里面逻辑太复杂, 把相关逻辑抽取成一个完整逻辑的函数, 保证可读性. 当然如果计算非常简单提取成变量也没问题, 函数是为了逻辑短路避免无用计算
    imycc
        11
    imycc  
       164 天前
    折行呗,大概长这样,也不用什么括号

    ```
    if cond_a \
    and cond_b \
    and cond_c:
    pass
    ```
    imycc
        12
    imycc  
       164 天前
    缩进被删了有点麻。if 折行之后下一行是两个缩进的距离,为了 if 里面一个缩进的语句区分开来
    rwecho
        13
    rwecho  
       164 天前 via Android
    pep8 会给加换行的
    imn1
        14
    imn1  
       164 天前   ❤️ 2
    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
        15
    chevalier  
       164 天前   ❤️ 2
    这种 if 很显然,你的程序设计有问题,逻辑划分和封装得不合理

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

    当然最好是想办法优化一下判断条件, 这么长的判断式可读性很差
    ilylx2008
        19
    ilylx2008  
       164 天前
    Python: 时间花在排版上
    msg7086
        20
    msg7086  
       164 天前
    @shawnbluce #6
    是不是可以把变量改写成 lambda 延迟执行,这样就支持短路了吧。
    GuangXiN
        21
    GuangXiN  
       164 天前
    把长 if 表达式提取成函数
    deplivesb
        22
    deplivesb  
       163 天前
    如果 if 条件太长,为什么不抽取成一个功能完备的函数,这样既可以解决 if 太长,还可以有概率复用
    panghu618
        23
    panghu618  
       160 天前
    变函数
    colatea
        24
    colatea  
       157 天前
    正常写,写完就格式化文档,反正以后也不看
    关于   ·   帮助文档   ·   API   ·   FAQ   ·   我们的愿景   ·   广告投放   ·   感谢   ·   实用小工具   ·   2205 人在线   最高记录 5497   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 00:36 · PVG 08:36 · LAX 17:36 · JFK 20:36
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.