没有学不会的python
函数是什么?
老调常谈,还是那老一套,学习一个东西前,先搞懂是什么,再来学习怎么用。
函数函数,如果你是刚经历过高考肯定很熟悉,数学中就经常出现这个名词,比如什么sin函数,cos函数之类的。哈哈,心疼一会高考生。
函数是什么呢?其实函数严格来说,可以分为数学函数以及计算机函数,数学函数嘛,大家都是有文化的人,应该都知道,且我讲的是编程,数学函数跟这个关系不大,这里就略过了。我们主要讲计算机函数。
计算机函数是什么?
官方的解释是这样的:
函数是指一段在一起的、可以做某一件事儿的程序。也叫做子程序、(OOP中)方法。
其实这段解释已经很直白了,对于初学者来说,困惑的点就是子程序这个词。在写代码的过程中,往往由于业务逻辑比较复杂,各种数据交互流程比较繁琐,出于数据安全、易于理解、松耦合、强内聚等特征的考虑,我们会把程序划分成多个模块,每个模块又划分多个类和多个函数。由于上述现象的出现,一个大的程序模块就有很多小的模块组成,然后在大的模块中会调用小的模块以实现某个功能点,此时小的模块就成为了子模块,也叫做子程序。
简单说吧,子程序就是一个实现特定功能的程序块,通常被主程序调用。
嗯,现在把子程序讲清楚了,那么这个跟函数有什么关系?其实吧,子程序换一种说法,也可以称作是函数。在不同的语言中,有时也称为方法,但在python中,如果子程序是处于模块中的就称作函数,如果是处于类中的,就称作方法。由于我这个系列里还没讲到面向对象,所以,我们忽略掉类的方法这个说法,现在暂且认为,子程序就是函数。
做一个比较形象的例子:
假设上述人的一天是主函数,那么吃饭上班睡觉就是子函数,只有在主函数中调用了子函数,才能组成人的一天。
函数有什么作用?
既然函数存在,那么就有它存在的道理。它的作用不仅有,而且特别重要。下面就随便列几个,更多的我就不说了,因为如果你没有编程基础的话,很多特性说了也理解不了,等于白说。
- 高内聚、低耦合---这个是编程语言中的一个非常重要的特征,尤其是面向对象语言中。高内聚指的是,实现同样目的的代码应该尽量放在一块,不要松散。低耦合指的是,函数与函数之间尽量解耦,不要处处关联,这样才不会出现一发而触动全身的情况。即不会因为改了某个函数的一句话,导致其它函数也不能用了。
- 易拓展---需求是跟着市场和甲方走的,产品要改需求,程序员就得加班,如果程序的代码结构很好,那么我们就可以只改需要改的函数,其它的不动,比如增加功能模块,增加参数。
- 可重复使用---当把某个功能代码高度集中在函数里面时,此函数就不依赖于其它函数而存在,因此,任何需要实现该功能的函数都可以通过调用这个函数来获取该功能。
- 易于理解---通过函数名称以及文档描述和注释,可以让自己以外的人更好的参与进来,而函数的存在,对于这种分工合作是个很好的表现形式,大家都不需要知道函数怎么实现的,只需要调用就可以了。
还有更多,以后你就会慢慢发现了。
如何定义函数?
函数的定义很简单,看下面:
def function_name(prama1,prama2): pass
def的意思就是声明后面的语句块是一个函数,function_name就是函数名称,param1、param2就是参数。到了这里,我有必要再说一下,因为面对着没有基础的同学,难免要多说一点,避免他们走弯路。我要说的是函数名称不是写死的function_name,上面的只是一种表现形式。就好比大家都有名字,但是我们大家都不叫名字,有的叫刘亦菲,有的叫马云。函数名称应该是根据所实现的功能来定的,参数名称也类似。
这里说一下什么叫做参数,参数可以看作是一个因变量,只有传入了参数,才能使函数产生不同的结果。参数不是函数必须的,可以构造一个不需要参数的函数,但是这个函数总会产生相同的结果。
下面看一下函数的示例:
def my_sum(param1, param2): return param1 + param2def my_diff(param1, param2): return param1 - param2
完了吗?那肯定不是,哪有这么简单。结合我自己的编程经验,还有以下的功力要传授给你们。
函数名称要有实际意义,切记假大空,更忌讳的是取一个毫无关系的名字
比如:我想定义一个扫描字符串的每个字符并输出的函数。有下面三个写法:
def scan_str(content): for s in content: print(s)def scan(content): for s in content: print(s)def a(content): for s in content: print(s)
第一个函数最优,从名字就看得出来就是扫描字符串。第二个次之,从名字看到出来是扫描,但是扫描啥不知道,扫描文件还是扫描病毒还是其他的?这就是范围过广,也就是假大空。第三个写出来是要被骂的,而且是往死里骂的那种,从函数名字根本看不出来是什么意思。你想象一下啊,如果一个几万行代码含有几百个函数的程序,全部名字都是abcd这样的名字,你会不会看疯掉?
函数应该要加上文档说明,复杂的语句要加上注释说明
这么做的原因是,一来方便日后自己查看代码,二来是方便别人接手你的代码。添加文档说明的方式如下:
def scan_str(content): """ 扫描字符串的每个字符并输出 :param content: 待扫描的内容 :return: 不返回任何结果 """ for s in content: print(s)
就是在函数声明下面,真正的代码实现逻辑上面,输入三次双引号就会自动生成一个待填充的文档说明结构,含有功能描述,参数描述以及返回值描述。未填充前的代码是这样的:
def scan_str(content): """ :param content: :return: """ for s in content: print(s)
函数的代码块不易过长,一般维持在15行以内为佳
代码语句块过长说明我们的功能划分的还不够细致,过于短说明我们过于精简,一般维持在15行以内为佳。当然这不是硬性标准,它不会报任何异常。只是这个是默认的python pep8国际编码规范,很多大公司都会有代码规范考核的,从一开始掌握这些对我们有好处。 是
函数的参数值和传参
上面有简单讲了参数是什么。但这还远远不够,python中的参数,是非常灵活且有趣的。目前来说,可分为四类,分别是必须参数、可选参数、位置参数、关键词参数。下面就这些一个个来说。
必须参数
必须参数就是必须要传递的参数,如果不传递就调用函数会报TypeError。比如我如果这样调用函数,就会报错:
def scan_str(content): """ 扫描字符串的每个字符并输出 :param content: 待扫描的内容 :return: 不返回任何结果 """ for s in content: print(s)scan_str()
由于scan_str有一个content参数,这个是必须参数,如果你不传递就调用这个函数,会爆出如下异常:
Traceback (most recent call last): File "D:/code/python/blog/main.py