Lambda functions λ 函数 更规范的使用

https://treyhunner.com/2018/09/stop-writing-lambda-expressions/

错误用法

lambda 赋给变量

  • 错误
1
normalize_case = lambda s: s.casefold()
  • 正确

    • 定义单行,正常函数
1
def normalize_case(s): return s.casefold()

多余的转换

  • 错误

    • 在 lambda 中又调用同样接口的函数

      1
      
      sorted_numbers = sorted(numbers, key=lambda n: abs(n))
  • 正确

    • 直接使用已有函数,不要多此一举

      1
      
      sorted_numbers = sorted(numbers, key=abs)

返回多个值

  • 错误

    • 这样会降低可读性

      1
      2
      3
      4
      
      colors = ["Goldenrod", "Purple", "Salmon", "Turquoise", "Cyan"])
      
      # * here
      colors_by_length = sorted(colors, key=lambda c: (len(c), c.casefold()))
  • 正确

    • 加了注释的简单,普通函数

      1
      2
      3
      4
      5
      6
      
      def length_and_alphabetical(string):
          """Return sort key: length first, then case-normalized string."""
          return (len(string), string.casefold())
      
      colors = ["Goldenrod", "Purple", "Salmon", "Turquoise", "Cyan"])
      colors_by_length = sorted(colors, key=length_and_alphabetical)

代码太简单导致的隐晦性

  • 错误

    • 虽然代码简单,但是只能表示表面意思,深层意思会丢失

      1
      2
      
      points = [((1, 2), 'red'), ((3, 4), 'green')]
      points_by_color = sorted(points, key=lambda p: p[1])
  • 正确

    • 完整的函数
    • 完善的注释,增加可读性

      1
      2
      3
      4
      5
      6
      7
      
      def color_of_point(point):
          """Return the color of the given point."""
          (x, y), color = point
          return color
      
      points = [((1, 2), 'red'), ((3, 4), 'green')]
      points_by_color = sorted(points, key=color_of_point)

reduce, map, filter 等 直接的隐晦性

  • 使用 operator 模块,增加可读性 https://docs.python.org/3/library/operator.html

    • 注:这是一个 reduce, map, filter 的辅助模块

      1
      2
      3
      4
      5
      6
      
      # Without operator: accessing a key/index
      rows_sorted_by_city = sorted(rows, key=lambda row: row['city'])
      
      # With operator: accessing a key/index
      from operator import itemgetter
      rows_sorted_by_city = sorted(rows, key=itemgetter('city'))
    • List, Tuple, Dict

      • 使用 operator.itemgetter('city'),直接可读性,用于

        • 这里创建一个元素访问器函数,用来提取 obj['city'] 属性
    • Dict 和 Object

      • 使用 operator.attrgetter('key')

        • 创建属性访问器函数
    • Object

      • operator.methodcaller('your_method_name', *args, **kwargs)

        • 函数调用工具

总结

  • 如果更需要可读性

    • 解决方法

      • 普通函数

        • 可以有名称,可以有充分的注释
      • operator 模块

        • methodcaller()
        • attrgetter()
        • itemgetter()

PEP 484 python 注解 和 typing