Python的函数思想及基本用法,划重点!
函数是一段可重复使用的、具有特定功能的语句块,通过函数名来定义和调用。经过定义,函数内的语句块成为一个整体,即“函数体”,可以通过使用函数名的调用从而实现函数内部语句块的重复使用。
在使用过程中,函数内部对调用者来说可以是完全未知的黑箱,调用者只要知道函数应该传入的参数是什么、返回的参数是什么这两点就可以无障碍调用。从此方面讲,函数就具有“封装”性。
使用函数最大的优点是提高代码的复用,并且可以进行模块化的程序设计。同样功能的代码多次使用,可以大幅的节省编程成本,提高编程效率,降低代码编程难度。同时,习惯使用函数编程,将实现不同功能的代码写成不同的函数,便于将编程问题和具体需求进一步细化,分而治之。
同一个程序的功能被划分为不同的小的功能模块,形成模块化设计布局,不仅使得程序具有很好的可读性,也便于程序的维护升级和兼容性提升。函数对内部封装的特性,使得只要在定义函数的部分更改其函数体的语句,就能实现该功能的升级维护,整个程序中调用该函数的部分也会得到更新。
1.基本使用
函数的使用可以包括四个步骤,即函数定义、函数调用、函数执行、函数返回。其中函数的定义部分尤为重要,其直接决定了函数应该怎么调用、函数的执行过程如何、函数返回什么值等等。
Python语言通过保留字def定义函数,语法形式如下:
def <函数名>(<参数列表>):
<函数体>
return <返回值列表>
函数名可以是任何P有效的Python标识符。
参数列表是调用该函数时传入给函数的值,可以是某个数据类型的单个参数,也可以是一个很多数据类型组成的参数列表,还可以没有任何参数(没有参数时,括号也不可以省略),视函数编写者的设计而定。参数列表以逗号分隔即可。
函数体则由具体的Python代码块组成,与前面学的普通Python代码没有任何差异,该代码块需要根据参数列表执行特定操作。
返回值列表是函数传出的参数,由return保留字建立,该列表也同参数列表一样,可以是任何的数据类型和任意数量大小的列表。当返回值列表的元素大小为0时,函数的执行只是对程序进行代码块的操作,不返回任何值,return需要省略。
函数的调用,通过函数名来调用函数功能,对函数的各个参数赋予实际值,实际值可以是实际的数据值,也可以是在调用函数前已经定义过的变量。
函数的执行,是参数传入以后,程序执行函数体功能代码的过程,其执行过程由函数体的代码决定。
函数返回,函数执行完毕后,函数将返回值列表返回到程序,并将控制权返回给程序。
函数定义及调用演示如下:
#定义返回三个数中的最大值和最小值的函数
def compare(a,b,c):#定义函数
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi#返回两个值
x = 1
y = 2
z = 3
#调用函数compare,并将两个返回值依次赋值给num1,num2
num1,num2 = compare(x,y,z)
print("最大值是{0},最小值是{1}".format(num1,num2))
#输出结果为:
最大值是3,最小值是1
函数的函数体一定需要书写至少一行的代码,当不希望函数做任何事时,可以使用pass保留字。保留字pass表示不进行任何操纵,起到占位的作用。演示如下:
def f():#定义空的函数
pass
f()#函数不会进行任何操作
编程中大量使用函数已经成为一种编程范式,叫做函数式编程。函数式编程的主要思想是把程序过程尽量写成一系列函数调用,这样能够使代码编写的更简洁易读,是中小规模软件最常用的编程方式。
在Python中,函数也是有类型的,可以通过type()函数来获得函数类型。函数类型是Python的内置类型,具体为function类型。当用type()检查调用的函数的类型时,返回的是函数返回值的类型。即函数调用优先执行,当函数执行完毕,函数将返回值和控制权返回给程序,type()函数检验的就不再是函数,而是返回值了。
2.参数传递
定义函数时参数列表中的参数,是形参数,没有实际意义。调用函数时传入的参数是实参,由出传入的参数赋予形参意义来执行程序。
函数的参数传递可以分为三种情况:可选的参数传递、参数名称传递、函数的返回值。其中可选的参数传递是指,在传入参数进函数时,可以省略掉一些参数,省略的参数用事先规定的默认值代替传入函数。演示如下:
def compare(a,c,b=2):#使用b-2规定如果缺失b,则默认b=2
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi
x = 1
z = 3
num1,num2 = compare(x,z)#与上一例子相比省略了y
print("最大值是{0},最小值是{1}".format(num1,num2))
#输出结果如下:
最大值是3,最小值是1
根据编程习惯,一般情况下参数列表都是先写非可选参数,可选参数放在后面。可选参数放在前面会报错,亲测。
参数传入函数还有另一种方法,即通过参数名称直接赋予形参意义。使用参数名称传入参数给函数,对参数的顺序没有要求。演示如下:
def compare(a,c,b=2):
ma = max(a,b,c)
mi = min(a,b,c)
return ma,mi
x = 1
z = 3
num1,num2 = compare(c=z,a=x,b=9)#顺序可以改变
#输出结果如下:
最大值是9,最小值是1
函数执行完毕,有可能需要对程序传出一些返回值列表,具体由return而定。返回值可以是0个,1个,多个。当返回多个参数时,这些参数形成了一个元组数据类型,由小括号和逗号分隔。例如(a,b,c)。元组和函数、整数、字符串等一样,是Python内置的数据类型,我们将在后续的课程中慢慢讨论。
函数可以没有返回值,当返回值是多个的时候,可以使用多个变量将返回值依次赋值给这些变量,在上例中已经演示过,不再重复演示。
3.变量作用域
根据程序中变量的所在位置和作用范围,可以将其分为全局变量和局部变量。全局变量值横跨多个函数,在整个程序中存在并发挥作用的变量;而局部变量则是指在一个函数的内部存在,并只作用于这个函数内部,函数执行完毕后便被内存释放,不在存在的变量。
例如如下代码:
def compare(a,c,b=2):
ma = max(a,b,c)#ma和mi都是局部变量
mi = min(a,b,c)#局部变量诞生于函数内部
return ma,mi#函数执行完毕后也将消失
x = 1#x,z,num1,num2都是全局变量
z = 3#全局变量自声明后除非主动消除,否则一直存在。
num1,num2 = compare(c=z,a=x,b=9)#顺序可以改变
在函数内使用全局变量需要使用global保留字。使用方法如下:
global <全局变量名>
演示代码如下:
s = "Python真简单啊"
def f():
#使用global保留字表明s是前面已经声明过的全局变量s
global s
print(s)
f()
#输出结果如下:
Python真简单啊
使用global保留字声明变量的作用域是Python语言中少有的需要再次声明的情形,由于作用域不同,这种声明不能省略。
4.代码复用
函数是程序的一种基本抽象方式,它将一系列代码组织起来通过命名供其他程序使用。这种封装的最直接好处就是能够很好的实现代码复用。当需要频繁的使用某种操作或是功能时,将这种操作或功能编写成函数封装起来,需要用的时候直接调用函数而不需要将该功能再写一遍,大大提高了编程效率。
以函数式编程为基础的模块化设计程序,就是通过函数的封装功能将程序划分为主程序和若干子程序,通过主程序和子程序之间的关系,将各个独立的功能程序组成一个有机可可协同的整体程序。因此,模块化设计以功能块为基本单位,一般有两个基本要求:
紧耦合:尽可能合理划分功能块,各个功能块内部耦合紧密。
松耦合:模块间关系尽可能简单,各个功能块之间耦合松散。
在编程中,耦合性指程序结构中各模块相互关联的程度,它取决于各模块间接口(即实现模块相连的入口,能体现两个功能模块之间的关系)的复杂程度和调用方式。耦合性是影响软件复杂程度和设计质量的一个重要因素。紧耦合指模块或系统间关系紧密,存在较多或复杂的相互调用,紧耦合的缺点在于更新一个模块可能导致其他模块变化,复用较困难。松耦合一般基于消息或协议实现,系统间交互简单。
松耦合代表了模块化,从系统观点来看,松耦合是程序的总体设计原则,也是函数使用的重要指导。
使用函数只是模块化设计的必要非充分条件,根据计算需求合理划分函数十分重要。一般来说,完成特定功能或被经常复用的一组语句应该采用函数来封装,并尽可能减少函数间参数和返回值的数量。