瞧瞧,这样的「函数」才叫 Pythonic
在机器学习中 , 我们经常需要使用类和函数定义模型的各个部分 , 例如定义读取数据的函数、预处理数据的函数、模型架构和训练过程的函数等等 。 那么什么样的函数才是漂亮的、赏心悦目的代码呢?本期教程 , 会从命名到代码量等六方面探讨如何养成美妙的函数 。 文末有给大家录的视频教程 , 大家可以按需学习 , 不清楚的地方也可以留言!
与多数现代编程语言一样 , 在 Python 中 , 函数是抽象和封装的基本方法之一 。 你在开发阶段或许已经写过数百个函数 , 但并非每个函数都生而平等 。 写出「糟糕的」函数会直接影响代码的可读性和可维护性 。 那么 , 什么样的函数是「糟糕的」函数呢?更重要的是 , 要怎么写出「好的」函数呢?
简单回顾
数学中充满了函数 , 尽管我们可能记不住它们 。 首先来回忆一下大家最喜欢的话题——微积分 。 你可能记得这个方程式:f(x) = 2x + 3. 这是一个叫做「f」的函数 , 含有一个未知数 x , 「返回」2*x+3 。 这个函数可能和我们在 Python 中看到的不一样 , 但它的基本思想和计算机语言中的函数是一样的 。
函数在数学中历史悠久 , 但在计算机科学中更加神通广大 。 尽管如此 , 函数还是存在一些缺陷 。 接下来我们将讨论一下什么是「好的」函数 , 以及在出现什么样的征兆时我们需要重构函数 。
决定函数好坏的关键
好的 Python 函数与蹩脚 Python 函数的区别是什么?「好」函数的定义之多让人惊讶 。 从我们的目的出发 , 我会把好的 Python 函数定义为符合以下清单中大部分规则的函数(有些比较难实现):
- 命名合理
- 具有单一功能
- 包含文档注释
- 返回一个值
- 代码不超过 50 行
- 幂等 , 尽可能是纯函数
命名
关于这个问题 , 我最喜欢的一句话(出自 Phil Karlton , 总被误以为是 Donald Knuth 说的)是:
在计算机科学中只有两个难题:缓存失效和命名问题 。
听起来有点匪夷所思 , 但整个不错的命名真的很难 。 下面就有一个糟糕的函数命名:
def get_knn(from_df):
我基本上在任何地方都见过糟糕的命名 , 但这个例子来自数据科学(或者说 , 机器学习) , 从业者总是在 Jupyter notebook 上写代码 , 然后尝试将那些不同的单元变成一个可理解的程序 。该函数命名的第一个问题是使用首字母缩写/缩略词 。 比起缩略词和并未普及的首字母缩写 , 完整的英语单词会更好 。 使用缩写的唯一原因是为了节省打字时间 , 但现代的编辑器都有自动补全功能 , 所以你只需键入一次全名 。 之所以说缩写是一个问题 , 是因为它们通常只能用于特定领域 。 在上面的代码中 , knn 是指「K-Nearest Neighbors」 , df 指的是「DataFrame」——无处不在的 Pandas 数据结构 。 如果另外一个不太熟悉这些缩写的编程人员正在阅读代码 , 那 TA 就会一头雾水 。
关于这个函数名称 , 还有另外两个小问题:单词「get」无关紧要 。 对于大多数命名比较好的函数 , 很明显函数会返回一些东西 , 其名字会反映这一点 。 from_df 也是不必要的 。 如果参数的名称描述不够清楚的话 , 函数的文档注释或者类型注释将描述参数类型 。
那我们如何重新命名这个函数呢?例如:
def k_nearest_neighbors(dataframe):
现在 , 即使是外行也知道这个函数在计算什么了 , 参数的名称(dataframe)也清楚地告诉我们应该传递什么类型的参数 。单一功能原则
「单一功能原则」来自 Bob Martin「大叔」的一本书 , 不仅适用于类和模块 , 也同样适用于函数(Martin 最初的目标) 。 该原则强调 , 函数应该具有「单一功能」 。 也就是说 , 一个函数应该只做一件事 。 这么做的一大原因是:如果每个函数只做一件事 , 那么只有在函数做那件事的方式必须改变时 , 该函数才需要改变 。 当一个函数可以被删除时 , 事情就好办了:如果其他地方发生改动 , 不再需要该函数的单一功能 , 那么只需将其删除 。
举个例子来解释一下 。 以下是一个不止做一件「事」的函数:
def calculate_and print_stats(list_of_numbers): sum = sum(list_of_numbers)mean = statistics.mean(list_of_numbers)median = statistics.median(list_of_numbers)mode = statistics.mode(list_of_numbers)print('-----------------Stats-----------------')print('SUM: {}'.format(sum) print('MEAN: {}'.format(mean) print('MEDIAN: {}'.format(median)print('MODE: {}'.format(mode)
- 智能手机市场|华为再拿第一!27%的份额领跑全行业,苹果8%排在第四名!
- 会员|美容院使用会员管理软件给顾客更好的消费体验!
- 行业|现在行业内客服托管费用是怎么算的
- 人民币|天猫国际新增“服务大类”,知舟集团提醒入驻这些类目的要注意
- 国外|坐拥77件专利,打破国外的垄断,造出中国最先进的家电芯片
- 技术|做“视频”绿厂是专业的,这项技术获人民日报评论点赞
- 面临|“熟悉的陌生人”不该被边缘化
- 中国|浅谈5G移动通信技术的前世和今生
- 页面|如何简单、快速制作流程图?上班族的画图技巧get
- 桌面|日常使用的软件及网站分享 篇一:几个动态壁纸软件和静态壁纸网站:助你美化你的桌面