在前面的文章中,已经提过,所谓编程,核心内容只有两块:数据的表示、数据的处理。数据的表示可以通过各种基本类型、容器类型的组合来实现;数据的处理,就是在顺序、循环、分支的框架下,对数据结构进行不断重新赋值。
刚开始学习编程的新手,似乎不太习惯使用用户自定义函数(User Defined Function, UDF)来编写数据的处理功能。习惯于在脚本中按顺序进行语句与表达式的堆砌。
如果数据处理的逻辑表简单的话,不使用函数也是可以的,毕竟够用就好。但是,如果数据处理的逻辑比较复杂的话,还是使用代码一行行堆积来实现功能,就不太合适了……
可以想象一下,要从一坨几百行、几千行、甚至更多行的代码中读懂处理逻辑,然后还要进行修改、扩充。单单只是读,可能都要吐了。
程序员最怕的有两件事:1)读别人的代码;2)读自己的代码。
所以,为了避免日后自己看吐或者把别人看吐,UDF还是需要学一下的。
函数的好处Python程序员首先应该考虑的代码整理工具就是函数(function)。与其他编程语言一样,Python的函数也可以把大段程序分解为多个小块儿,并且用直观的名字表示每块儿代码的用途。这样可以让代码更好理解,也更容易复用与重构。
简单梳理一下,在编程中,使用函数的好处有如下:
代码的复用:一次定义,多次调用。
提高代码的可维护性:代码复用的情况下,一次修改,多处生效。
逻辑分离与模块化:代码不再是一整坨,而是一块块的。
提高代码的可读性:代码逻辑分离与模块化之后,自然更加易读、易于维护。
提高可扩展性:使用函数,可以更加容易进行功能的添加、或者修改。
易于调试:模块化的好处,可以各自独立进行功能的调试,快速定位到问题。
函数的基本用法编程语言中的函数概念,可以类比于数学中的函数的概念。函数的用途在于对数据进行处理,所以,通常需要有输入数据、数据处理逻辑、和输出数据。
在Python中自定义一个函数,可以如下操作:
可以大概看到一个函数的构成,主要包含:
def关键字:用于定义函数。
函数头:函数名(参数列表),参数列表可以为空。
docstring:函数的说明文档,以三个引号括起来的字符串,可以没有,如果有,需要放在行数体内的第一行。
函数体:数据的处理逻辑代码。
返回值:使用return语句将要输出的数据进行返回,可以没有,没有的话,就是返回None。
以上只是一个函数的定义,要把函数的功能用起来,需要对函数进行调用:
调用函数非常简单,只需要将参数对应传入即可。通过赋值语句接收函数的返回值。
参数默认值的用法Python支持在函数的定义过程中,给部分参数设置默认值,从而支持当默认情况满足需求的情况下,减少参数个数的传递,从而更加便于使用。而且,可以通过参数默认值,增加函数的灵活性。比如:登录用户,能够获取到用户名,如果未登录用户,则以‘游客’来称呼:
执行结果:
需要注意的是,带默认值的参数,只能出现在参数列表的最后,可以是多个,否则会报语法错误。
这个语法规定,应该很好理解,如果你是Python解释器,你怎么处理带默认值的参数,才能不会出现二义性呢。
lambda函数(匿名函数)本着能用一行代码解决的事情,绝不写第二行的理念。有些情况下,使用def定义函数,有点繁琐了……
好在Python提供了lambda函数的支持。
lambda函数一种匿名函数,可以实现在一行代码中定义一个功能相对简单的函数。直接上代码:
前面两个简单函数的lambda实现,确实少了一行代码。但是,其实lambda函数,更多地应用于将函数作为参数传递的场景,比如,当我们使用内置函数sorted()时,先看下sorted()函数的说明文档:
函数中有个key参数,用于传递一个表示排序规则的函数,函数返回一个新的list,包含排序之后的数据,而不会修改原来的对象。此外,sorted函数还有一个带默认值的参数reverse=False,表示默认按照升序排列。
以一个关于成绩排序的场景,来简单使用一下该函数:
执行结果:
这里,定义了一个get_chinese()的函数,作为key的参数。由于排序的规则比较简单,更适合使用lambda函数。
执行结果:
总结由于篇幅所限,这篇文章只介绍了关于函数的优点,以及函数的一些基础用法。最后在介绍lambda函数的时候,以一个简单的实际案例做了演示。案例中用到的rich和faker第三方框架,在前面的文章中已经介绍过,感兴趣的可以自行查阅。