在学习函数之前,我们写代码都是一行一行不停的往下累积。
例如:我们写一个爬取图片的爬虫。
这种编程方式叫做面向过程。是一种以过程为中心的编程思想。面向过程是一种最实际的思考方式。比如拿学生起床这件事说明面向过程,粗略的将过程拟为:
起床
穿衣
洗脸刷牙
去学校
而这四步就是一步步完成的,它的顺序很重要,你只需要一步步实现就行了。
对比到上面的代码,它的过程是:
下载页面html源码
提取页面中的图片url
循环下载和保存图片
这个过程是按照顺序,不能改变。
面向过程方式的优点是,直观,快速,最贴近实际流程。但是它的缺点也很明显。当实际业务流程发生了改变,那么我们的程序也相应需要改变,而这个改变可能是推翻前面所有的重写。另外在实际业务中,如果有某步操作需要重复进行,那么我们需要重复写多次。
例如下面的案例:
总结:
面向过程的编程方式的缺点:
不便于维护修改升级
代码有大量冗余
为了解决这个问题,计算机科学家发明了另外一种编程方式,那就是函数编程。
例如下面的案例:
这段代码以函数式编程的方式实现了前面那个爬虫。首先单从代码量上来看,比前面那种写法还多些,感觉还不如面向过程的方式。没错,在简单任务上,面向过程会比函数式更加的直观和简洁。但是仔细看看我们这段代码,我们将这个爬虫分成了四函数:
下载数据:负责通过url下载相对应的数据
提取页面图片url:负责在html源码中提取图片url
保存图片:负责将下载下来的图片保存为文件
主函数:负责将上面3个功能函数安装逻辑顺序组织起来实现爬虫的功能
这就好比我们加工某个产品的流水线,将其中可以单独拿出来的工序独立,不同的工种只负责一部分,最后进行组装。当我们要增加新的功能,升级产品时,只需要将需要升级的那部分做改变就可以,而不用推翻所有的工序。那么对比到我们这个爬虫。
如果网站升级了,出现了反爬措施,我们只需要修改下载数据函数,其他函数不需要做调整。如果网站升级了页面,我们也只需要修改提取页面url中的正则表达式即可,又或者网站的加载流程改变,那么修改主函数的逻辑即可,在维护升级上减少了大量的工作。这种方式还有一个好处,就是方便其他人来使用我们的程序,他们不需要知道程序的具体逻辑,只需要在他们的程序中引用函数,然后调用即可。
综上,编写函数将会是我们今后工作的主要内容。
那么在python中如何编写一个函数呢?
如下图:
在python中一个标准函数由四个部分组成
1.函数头
函数头是为了告诉python解释器,现在我要定义一个函数。它由关键字 def、函数名、参数组成。格式如下:
def 函数名([参数1,参数2,...]):
注意一定要有冒号,可以没有参数,小括号一定要有,这是语法没有道理可讲,必须记住。
2.函数接口(可以在pycharm随便找个系统函数展示)
函数接口是为了说明函数的作用,和参数类型,以及返回值,方便其他人调用,
语法格式是,缩进函数头四个空格,由"""包裹起来
注意:新手会忽视这个,而这个是一个体现程序员素养的最重要的地方。
3.函数体
函数体就是这个函数通过语句完成它的功能,业务逻辑就体现在这里了
语法格式,缩进函数头4个空格
4.返回语句
返回语句的作用就是将函数处理完的结果返回给它的调用者。
由关键字return和值组成 多个值可以用逗号隔开
注意:python中如果函数没有返回语句,会默认返回None
ok,我们学会了怎么定义一个函数,那么我们怎么去使用它呢?在这之前我们必须了解,解释器是怎么处理
定义函数这个事情的
这个过程其实跟定义一个变量一样的,所以函数名的命名方式和变量一样。
想要使用一个函数首先需要定义:
要让解释器先把函数加载进内存然后才能调用。
调用函数非常简单,只需要函数名后加个括号,传入参数即可。
调用函数可以在程序的任何地方,只要内存中已经定义好了这个函数。
到这里,我们学会了如何定义和调用函数,我们其实已经具备了编写简单程序的能力了。
我们来看一个案例:编写一个函数,实现解开任意一元二次方程
一元二次方程形式:ax2+bx+c=0(a≠0,且a,b,c是常数)
然后我们调用这个函数
接下来我们根据这个函数我们来分析一下函数的参数:
形参:定义函数的时候,写的参数,a,b,c叫做形式参数,简称形参。在函数没被调用的时候,它没有任何意义
在调用时,必须传入参数,所以也叫必须参数。
实参:调用函数的时候,写在括号中的1,2,1叫做实际参数,简称实参。当我们把实参直接写在括号中的时候
位置参数:它会按照位置,与实参一一对应,所以也叫位置参数。那么这是形参中的 a, b, c分别就指向了1,2,1
缺一不可,缺了会报错
例如:
多了也会报错:
再次,强调一遍,这种按位置传参的方式,实参与形参按位置一一对应,如果传参顺序不一样,结果也是不一样的。
有时候我们也看到这种传参写法:
这种方式是以键值对的方式传参,所以也叫作关键字参数,因为显式的指定了形参和实参的对应关系,所以它的顺序无所谓。但是当关键字参数,和位置参数一起使用的时候,关键字参数需要写在后面,这是语法。
并且也要保证,不能一个形参传递多个实参
例如下面这种情况:
我们改变一下需求:
我们需要计算的方程,大部分情况都是ax2+bx+3=0,按照我们之前的函数,我需要每次都要传入3这个实参,但是大家都知道程序员很懒的,所以就想办法啊,能不能实现不传入实参,让形参c默认等于3。
传入实参的时候又能接收。这样就出现了默认参数的情况,我们修改函数如下:
注意:定义函数式,默认参数一定要写在必须参数的后面,这个是语法
同学们高潮来了哦,提高来了哦,需要知道基本的数据类型。人类的欲望,客户的要求是无止境的。
需求:要求写一个函数,当传入2个数的时候就求和,传入3个参数就计算一元二次方程。
也就是这个函数接收参数的个数是不确定的,是动态的。
程序员就是折腾的命。任务也要完成啊,所以就又出现了动态参数,函数如下:
调用结果:
在定义函数的时候,实参写成*args(星号是关键字,args是变量名,但是一般都写args,是规范),那么我们在调用函数时,所有传入的多余的位置参数都会被args接收生成一个元组。
注意多余这两个字
动态参数可以和其他类型的形参一起定义,但是要写在默认参数的后面。
说道这里,动脑筋的同学就又要问了,那如果传入多余的关键字参数怎么处理呢?
所以就出现了**kwargs(**是关键字,kwargs是变量名,一般都这么写),调用函数时,所有传入的多余的关键字
参数都会被kwargs接收,生成一个字典。
python中的函数就给大家介绍完了。
领取专属 10元无门槛券
私享最新 技术干货