第 6 课 Python函数和模块
1. 函数介绍
在Python 语言中,函数可分为内置函数和自定义函数。
- 内置函数也称作内建函数,是Python 自带的函数,无需导入任何函数库即可直接调用。常用的内置函数有print()、input()、range()等。
- 自定义函数就是将一段有规律的、可重复使用的代码定义成函数,以提升代码的复用率和可维护性。
1.1 函数定义
在Python 语言中,函数通常是由函数名、参数列表以及一系列语句组成的函数体构成的。函数定义的一般格式如下:
def 函数名(参数列表):
函数体
- 函数代码块以关键字“def”开头,后接函数标识符名称和形参列表;
- 为方便后期维护,函数标识符名称最好能够体现出函数的功能;
- 参数列表用于设置该函数可接收的参数,多个参数之间用逗号“,”分隔;
- 任何传入的参数和自变量必须放在括号“()”内;
- 函数内容以冒号“:”起始,且严格统一缩进;
- 函数的第一行语句可选择性地使用文档字符串,即函数说明;
- 函数都有返回值,默认返回“None”。
注:创建函数时,即使函数不包含任何参数,函数名后面的小括号“()”仍需保留。
1.2 形参和实参
在编程语言中,函数定义时采用形参,调用时采用实参。两者的功能是数据传送。
- 形参(parameter):形参,即形式参数,不是实际存在的变量,因此又称虚拟变量。形参是在定义函数名和
函数体时使用的参数,用于接收调用该函数时传入的参数,其作用域一般仅限函数体内部。 - 实参(argument): 实参,即实际参数,是在调用时传递给函数的参数,可以是常量、变量、表达式、函数等,其作用域根据实际设置而定。
无论何种类型的实参,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。
以下图代码为例,函数area()定义处的“width”和“height”是形式参数,而函数体外定义的变量“w”和“h”则是实际参数。
#计算矩形面积的函数
def area(width , height):
return(width*height)
w=4
h=8
print("Width=",w,"Height=",h,"Area=",area(w,h))
运行后,打印结果如下:
Width= 4 Height= 8 Area= 32
将实参“w”和“h”传入函数体后,相应的值就被赋予形参“width”和“height”。形参“width”和“height”的作用域只限于area()函数体内,而实参“w”和“h”的作用域则根据外部调用处的设置而定。
1.3 函数返回值
在函数执行完成后,系统根据函数的具体定义,将某些值反馈至外部调用者,该值则称为函数的返回值。
在Python 语言中,当函数运行到return 语句,即表示函数执行完毕,会返回指定值。若函数内部没有return 语句,则函数默认返回“None”。以下图代码为例,调用add()函数后,该函数返回“x+y”的运算结果,并将值赋予变量“result”。
def add(x,y):
print("x+y",x+y)
return x+y
result=add(x=1,y=2)
print(result)
执行后,打印结果如下:
x+y 3
3
需要注意的是,在Python 语言中,函数可拥有多个返回值,以下图代码为例:
def calculate(x,y):
print("x+y",x+y)
print("x*y",x*y)
return x+y,x*y
a,b=calculate(x=1,y=2)
print(a,b)
执行后,打印结果如下:
x+y 3
x*y 2
3 2
calculate()函数内有两个返回值,分别是“x+y”和“x*y”,调用该函数后,两个返回值分别赋予变量“a”和变量“b”。
2 函数传递
函数参数分为可变类型和不可变类型,两者的调用结果是不同的。
2.1 可变类型
可变类型的调用类似C++的引用传递。如果传递的参数是可变类型(见第3课),如列表、字典等,函数内部对传入参数的修改会影响到外部变量。
以下图代码为例,change_int()函数内部对传入的列表“list_01”进行修改后,外部的变量也会被更改。change_int()函数内的“append”作用为向列表内添加元素,这里我们将列表“[1,2,3]”作为元素添加到列表list_01。
def change_int(list_01):
list_01.append([1,2,3])
print("函数内修改后的变量:",list_01)
list_01=[10,20,30]
change_int(list_01)
print("函数外变量的值:",list_01)
执行后,打印结果如下:
函数内修改后的变量: [10, 20, 30, [1, 2, 3]]
函数外变量的值: [10, 20, 30, [1, 2, 3]]
2.2 不可变类型
不可变类型的调用类似C++的值传递。如果传递的参数是不可变类型(见第3课),如整型、字符串、元组等,函数内部对传入参数的修改不会影响到外部变量。
以下图代码为例,变量“b”指向int 对象“2”,在传递至unchange_int()函数时,按传值方式复制变量“b”,即变量“a”和变量“b”都指向了同一个int 对象“2”。
然而,当执行“a = 10”,变量“a”指向新生成的int 对象“10”。因此,外部变量未发生改变,程序打印的数值应为“2”。
def unchange_int(a):
a=10
b=2
unchange_int(b)
print(b)
3 参数类型
3.1 位置参数
调用函数时,每个实参都按照位置顺序关联至对应的形参,这种关联方式即为位置参数。
以下图代码为例,调用describe_student()函数时,需要依次提供姓名和年龄这两个参数,则实参“Jack”和“18”分别存储至形参“person_name”和“student_age”中。
def describ_student( person_name ,student_age):
print("My Name is ",person_name)
print(person_name +" is " + student_age+" years_old")
describ_student('jack', '18')
执行后,打印结果如下:
My Name is jack
jack is 18 years_old
3.2 默认参数
自定义函数时,可以为每个形参指定默认值。调用函数时,若给形参提供了实参,则采用指定实参;否则,采用形参的默认值。
以下图代码为例,将形参“student_age”的默认值设定为“18”。当调用describe_student()函数时有为形参“student_age”提供实参,则采用指定实参,此处为“20”;否则,采用默认值“18”。
def describ_student( person_name ,student_age='18'):
print("My Name is ",person_name)
print(person_name +" is " + student_age+" years_old")
describ_student('jack', '20')
describ_student('jack')
执行后,打印结果如下:
My Name is jack
jack is 20 years_old
My Name is jack
jack is 18 years_old
3.3 不定长参数
在Python 语言中,函数还可以定义不定长参数,也叫可变参数。在标识符前面添加“*”即可将对应参数定义为不定长参数。
以下图代码为例,将参数“number”定义为不定长参数后,在调用calculate()函数时,即使传入参数不是列表或元组,函数也可直接使用。
def calculate( *numbers):
sum=0
for n in numbers:
sum = sum+n
return sum
print(calculate(1,2,3,4))
print(calculate())
执行后,打印结果如下:
10
0
3.4 关键字参数
关键字参数就是采用“形参名称-值”对的方式进行参数传递。通过此方式指定函数实参时,不再需要与形参的位置完全一致,只需确保参数名称正确。
以下图代码为例,在传递参数时,即使调整了参数顺序,函数仍然能够正常输出。
_student( person_name ,student_age):
print("My Name is ",person_name)
print(person_name +" is " + student_age+" years_old")
describ_student(person_name='jack',student_age= '20')
执行后,打印结果如下:
My Name is jack
jack is 20 years_old
3.5 关键字参数
当需要限制参数只能按关键字进行传递时,可以采用命名关键字参数。在自定义函数时,用“*”分隔形参,“*”后面的形参即为命名关键字参数。
以下图代码为例,“*”后面的形参“live_city”是命名关键字参数。因此,在传递参数时,它必须采用关键字参数的形式,否则程序会出现报错。
def describ_student( person_name ,student_age ,*, live_city):
print("Name : ", person_name)
print("Age : ", student_age)
print("City:",live_city)
describ_student('jack', '20',live_city="HangZhou")
执行后,打印结果如下:
Name : jack
Age : 20
City: HangZhou
4 模块介绍
一般情况下,模块(module)就是一个后缀名为“.py”的文件。此外,还有其他可作为module 的文件类型,如“.pyo”、“.pyc”、“.pyd”、“.so”、“.dll”,但Python 初学者暂不需要接触相关内容。
将能够实现某一特定功能的代码封装为一个独立的模块,这样既可以方便其它程序或脚本导入及使用,又可以有效避免函数名和变量名发生冲突。模块的来源有三种:
- Python 内置模块(标准库);
- 第三方模块;
- 自定义模块。
当需要调用某个模块的函数,需要先通过import 语句导入该模块后,再对函数进行调用。常用的导入方法有两种(中括号“[]”里的内容可省略):
- import 模块名称[ as 别名]:使用这种语法格式的import 语句,会导入指定模块中的所有成员(包括变量、函数、类等)。当需要使用模块中的成员时,需用该模块名(或别名)作为前缀。
- from 模块名称import 成员名称[ as 别名]:使用这种语法格式的import 语句,只会导入模块中指定的成员,而不是全部成员。同时,当程序中使用该成员时,无需附加任何前缀,直接使用成员名(或别名)即可。
注意:采用“from 模块名称import *”的形式也可以导入指定模块的所有成员,但不推荐此操作。