Python中逗号的那些事

March 9, 2018, 11:51 p.m.

最近同事查的一个 Bug,是数据类型的错误,预期是 int 类型的,然后报错信息里显示是 tuple 类型,同事被这个事折磨了快1整天,把整个调用链的数据都查了个遍,最后发现是一个逗号导致的,如下:

gid = curr_gid,
# gid 和 curr_gid 预期都是整型
# 最终 gid 的值为 tuple 类型, 如:(1,)

我对这个事情仔细分析了下:

  • 这个语法不难,有些经验的开发人员,都是了解的,而且同事也是知道的
  • 这个语句非常简单,在读的时候,会十分快速,逗号在整个视觉上的占比极其小,非常容易忽略
  • 由于语法是合法的,所以 PyCharm 也不会报错
  • 还有使用习惯上的原因,有些开发者习惯后面补上一个逗号,如:
# === list时 ===
[1, 2, 3]
# 等价于
[1, 2, 3, ]

# === dict时 ===
dic = {
  'a': 'a',
  'b': 'b'
}
# 等价于
dic = {
  'a': 'a',
  'b': 'b', 
  # 末尾加了逗号后,还有一个好处,就是复制粘贴方式
  # 不用刻意地去删除最后一个逗号
}

为什么有些开发者会有这样的习惯呢?

是因为被 tuple 类型的逗号坑过,而且有些书籍里也推荐这么做

(1)
# 不等价于
(1, )

(1) # 结果为1, 类型为 int 类型
(1, )  # 结果还是(1, ), 类型为 tuple 类型

上面分析了那么多原因,感觉像是在找借口,Trouble Shooting 能力不行就是不行

我觉得<找问题>和<避免问题的发生>,要分开来看,从以下方面来避免(开发阶段):

  • 将这个 Bug 的修复过程与收获分享出来
  • 逗号优先原则,且成为部门内的开发规范,增强小伙伴们对逗号的敏感程度,培养在意识中寻找逗号的习惯,如下:
# 除上以上的例子,还有:

# (1) list 的 append 操作
queue.append(2)
# 等价于
queue += 2, # 2后面有个逗号

# (2) 多个变量在一行赋值
a = 1
b = 2
# 等价于
a, b = 1, 2 # 在一行中用逗号分隔两个变量名

# (3) return 语句的返回值
def func():
  return 1, 2
a, b = func() # 接受时使用两个变量
c = func()  # 使用1个变量,结果为 tuple 类型

总结

要想避免一个问题的发生,只能去正视它,面对它,也就是要不断地去使用它

运行环境

  • Python:2.7.10
  • 个人计算机:iMac
  • 操作系统:macOS
  • 处理器:2.9GHz 四核 Intel Core i5
  • 内存:8GB 1600MHz DDR3

返回首页