以下两种风格 Python 写法,请问大家倾向哪种:)

2018-12-10 22:19:28 +08:00
 lucat

看到不同的同事代码,表达同一个意思,主要 if 部分以下哪种写法比较好些:)

第一种写法

def xxxx(ph, sin_id):
    """
    
    """
    
    with OracleConnect(xxxx) as db_oracle:
    	
        sql = u"xxxxx"
        has_data, sql_data = db_oracle.get_one(sql)
        
        # 第一种写法
        if has_data:
            calculate_func = "rollback"
            task_id = sql_data.get("task_id", "")
        else:
            calculate_func = "calculate"
            task_id = sin_id
            
	return task_id, calculate_func

第二种写法

def xxxx(ph, sin_id):
    """
    
    """
    
    with OracleConnect(xxxx) as db_oracle:
    	
        sql = u"xxxxx"
        has_data, sql_data = db_oracle.get_one(sql)
        
        # 第二种写法
        calculate_func = "rollback" if has_data else "calculate"
        task_id = sql_data.get("task_id", "") if has_data else sin_id   
        
   	return task_id, calculate_func

第一种写法,比较直接,清晰明了,但有同事说不够 pythonic

第二种写法比较 pythonic,但是类似写法,对于刚接手别人代码的同事,就要稍微绕一下才能读懂。

由此拓展,想到在写业务逻辑中,经常会有 if 语句的判断,请问大家是怎么选择代码风格的:)

8946 次点击
所在节点    Python
107 条回复
misaka19000
2018-12-10 23:21:21 +08:00
显然是第二种
liyoubin37
2018-12-10 23:27:08 +08:00
前几天看到的一种写法,比楼主的第二种简洁,但不光接触过的需要绕一下才能看懂。
return [("calculate",sin_id),("rollback",sql_data.get("task_id", ""))][has_data]
VDimos
2018-12-10 23:28:15 +08:00
rust 里推荐第二种,我觉得 rust 的编码风格很不错
AX5N
2018-12-10 23:32:11 +08:00
只从内涵考虑的话。第二种是两次控制流分别用于求两个不同的东西。如果 calculate_func 和 task_id 的关系不大的话,应该用第二种,如果关系大的话,应该用第一种。

这里应该用第一种吧
WilliamYang
2018-12-10 23:42:48 +08:00
两个变量都是根据 has_data 而变化, 因此这里不宜用第二种, 除非只是一个变量的取值. 如果有 if has_data 下有更多的变量赋值, 并且使用了第二种写法, 可能想打人
weakish
2018-12-10 23:44:45 +08:00
像 @monkeylyf 指出的,第二种写法不能让人一眼看出来,这两个变量的取值都取决于`has_data`,所以第二种写法不好,第一种好。

如果偏爱第二种的风格,那得这样写:

calculate_func, task_id = ("rollback", sql_data.get("task_id", "")) if has_data else ("calculate", sin_id)

其实我个人是喜欢第二种风格的,并不像 @xpresslink 说的“本质上是一样的”,第二种写法,可以确保你不会无意中遗漏 else 的情况——像 Haskell 和 OCaml 等一堆函数语言里,if then else 都是第二种写法。

但是 python 这个东西就和 lambda 一样,都是设计来让你写很短的东西的。设想一下,以后可能需求变动,不止一个条件判断,不止赋值两个变量,第一种写法可以很方便地加 elif,可以很方便地多加几行赋值语句。而第二种写法呢?当然,可以啦,条件判断嵌套,元组可以加元素,但是这么搞,可读性会很差。

所以鉴于 python 的设计限制,虽然我喜欢第二种写法,但我还是会用第一种写法。
j2gg0s
2018-12-10 23:46:56 +08:00
大段复杂逻辑用第一种,如果只是图例的话用第二种;

认为不太直观的,如果 Python 不是你的主要语言的,我觉得可以接受,要不然退教保平安把.
第二种类似的表达式,在大多数 py 项目里面是被普遍应用的,而且确实可以节省大量的代码
我随便帮你捞几段
https://github.com/celery/celery/blob/master/celery/events/dumper.py#L71
https://github.com/celery/celery/blob/master/celery/events/dispatcher.py#L183
https://github.com/celery/celery/blob/master/celery/events/state.py#L122
weakish
2018-12-10 23:51:03 +08:00
@liyoubin37 直觉上,has_data 的值应该是 True 和 False,而不是 0 或 1,这种写法是利用了 Python 的布尔值和整数值之间的隐式转换,我不喜欢。而且习惯上,has_data,正常的思路,是先写有数据的情况,再写没数据的情况,而这种写法还要颠倒一下,看起来很别扭。

这种写法更适合条件本来就是整数的情况(因为 python 里没有 switch ... case 语句)。
ToT
2018-12-10 23:52:11 +08:00
逻辑复杂的时候,还是第一种看起来明白阿。没必要刻意去追求行数精简。
weakish
2018-12-10 23:53:48 +08:00
@agdhole 这就是三元啊,只不过和大多数语言的三元的顺序不大一样而已。
cnt2ex
2018-12-11 00:02:30 +08:00
主要是作用域问题,虽然在 python 里没有问题,但其实第一种写法里那两个变量的作用域只在 if 里。
而我如果把 return 放进 if 里,会导致两个分支都有相同的代码。
所以我个人更偏向于:
calculate_func, task_id = ("rollback", sql_data.get("task_id", "")) if has_data else ("calculate", sin_id)
j2gg0s
2018-12-11 00:11:33 +08:00
@cnt2ex 作用域看你申明在哪里把? python 里面不用申明。不针对的说一句,你这个写法我觉得很不合适
leido
2018-12-11 00:15:15 +08:00
我看你同事就是傻逼
SaltyFishMo
2018-12-11 00:35:19 +08:00
@liyoubin37 这种写法,无论 has_data 的值是什么,都会执行 sql_data.get("task_id","")方法吧,是不是在一定程度上降低了效率呢?
liprais
2018-12-11 00:42:19 +08:00
30 秒看不懂的,以后都要重写
随便了,前人挖坑后人填坑呗
cgsv
2018-12-11 00:50:50 +08:00
@SaltyFishMo 跟第一种等价,false 时不执行
Yvette
2018-12-11 01:42:25 +08:00
没有代码规范的前提下,第二种显然比较直观,也不容易出错。
menc
2018-12-11 02:26:13 +08:00
result_mapping = {
'1': ('rollback', sql_data.get("task_id", "")),
'0': ('calculate', sin_id)
}
return result_mapping(has_data)
menc
2018-12-11 02:26:31 +08:00
@menc
最后括号改成方括号
xiaket
2018-12-11 06:02:32 +08:00
我觉得你同事只怕是对 Pythonic 有什么误解.

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

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

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

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

© 2021 V2EX