• Python 的语法很容易把复杂的意思挤到同一行表达式里,这样写很难懂。
  • 复杂的表达式,尤其是那种需要重复使用的复杂表达式,应该写到辅助函数里面。
  • if/else 结构写成的条件表达式,要比用 or 与 and 写成的 Boolean 表达式更好懂。

    一个例子

    在处理网页,或者说处理字符串时,我们经常获得到一个字典,对于字典里的键值对的处理挺关键的。然而有些朋友过度使用 Python 的语法特性,为了炫技,写成很复杂的难以理解的单行表达式,就有点小题大做了。

  • 比如这样一个栗子。

    1. from urllib.parse import parse_qs
    2. # 解析字符串,返回字典
    3. my_value = parse_qs('red=5&blue=0&green=', keep_blank_values=True)
    4. print(my_value)
    5. # {'red': ['5'], 'blue': ['0'], 'green': ['']}
  • 对于上面待处理的字典,我们对其值感兴趣。

  • 也就是我们想查询我们需要的值。
  • 现在一个目标是,若待查询的参数没有出现在字符串中,我们希望返回默认值 0,而不返回 None 等。该如何处理呢?
    • 也许我们会考虑 dic.get(key, defalt=None)
    • key 指代键,如果查不到对应值,返回第二个参数 None
  • 对于想要的目标,我们做出以下一步步调试。

    复杂方式_1

  • 空字符串、空列表及零值,都会评估为 False。

    1. # For query string 'red=5&blue=0&green='
    2. red = my_value.get('red', [''])[0] or 0 # or 操作符
    3. green = my_value.get('green', [''])[0] or 0 # 如果 or 前判断 False
    4. opacity = my_value.get('opacity', [''])[0] or 0 # 赋值 or 后语句
    5. print('Red: %r' %red) # %r 用 rper()方法处理对象
    6. print('green: %r' %green) # 打印时能够重现它所代表的对象
    7. print('opacity: %r' %opacity)
    8. # Red: '5'
    9. # green: 0
    10. # opacity: 0

    炫技方式_2

    1. red_1 = my_value.get('red', [''])
    2. red_1 = int(red_1[0]) if red_1[0] else 0
    3. print(red_1)
    4. # 5

简单方式_3

  1. green_1 = my_value.get('green', [''])
  2. if green_1[0]: # 如果有值
  3. green_1 = int(green_1[0])
  4. else:
  5. green_1 = 0
  6. print(green_1)
  7. # 0

范式_4

  • 用简单函数的表示来取代复杂的表达式。
    1. def get_int_value(dic_kv, key, default=0):
    2. value = dic_kv.get(key, [''])
    3. if value[0]:
    4. return int(value[0])
    5. else:
    6. return default
    7. print(get_int_value(my_value, 'opacity'))
    8. print(get_int_value(my_value, 'red'))
    9. # 0
    10. # 5