Python中的函数
-
函数的概述
-
函数的定义
-
形参和实参
-
函数返回值
-
函数分类
- 内置函数
- 自定义函数
-
函数的参数
- 参数种类
- 位置参数
- 默认参数
- 不定长参数
- 关键字参数
- 命名关键字参数
- 参数组合
-
函数式编程
- 高阶函数
- 匿名函数
一、函数的概述
在程序设计中,函数的使用可以提升代码的
复用率
和可维护性
。
二、函数的定义
函数定义的一般格式如下:
def 函数名(参数列表):
函数体
函数名后的
一对括号
是不能省略
的。
# 矩形面积area()
def area(c, k):
return c * k
# 欢迎
def welcome(name):
print("Welcome ", name)
# 调用welcome函数
welcome('张三')
# 调用area函数
w = 4
h = 9
print("width=", w, "height=", h, "area=", area(c, k))
有return的函数直接用Print打印输出,没return的函数直接用
在Python语言中定义一个具有特定功能的函数需要符合以下规则:
- 函数代码块以def关键字开头,后接函数标识符名称和形参列表;
- 任何传入的参数和自变量必须放在圆括号内;
- 函数的第一行语句可以选择性地使用文档字符串(即函数说明);(函数头后的第一个字符串称为 docstring(文档字符串 - documentation string 的缩写),用于简单地解释函数的功能比如welcome,可以使用
function_name.__doc__
来访问。)- 函数内容以冒号起始,并且严格统一缩进;
- 函数都有返回值,默认返回None。
三、形参和实参
在编程语言中,函数定义时用的是形参,调用时用的是实参
形参(parameter)
,全称为"形式参数"
,不是实际存在的变量,又称虚拟变量。形参是在定义
函数名和函数体的时候使用的参数,目的是用来接收调用该函数时传入的参数。
实参(argument)
,全称为"实际参数"
,是在调用
时传递给函数的参数。实参可以是常量、变量、表达式、函数等。无论实参是何种类型的量,在进行函数调用时,它们都必须具有确定的值,以便把这些值传送给形参。形参和实参的功能是数据传送。
在调用函数时,实参将赋值给形参。必须注意实参的个数、类型应与形参要
一一对应
,并且实参必须要有确定的值
。形参的作用域一般仅限函数体内部,而实参的作用域根据实际设置而定。对于函数形参列表,默认情况下函数调用时的参数值与参数列表声明中定义的顺序是一致。Python语言也允许函数调用时参数顺序与声明时不一致,即显示指明关键字参数,并根据参数的指定进行赋值。
def func(x, y):
print('x+y=', x + y)
print('x*y=', x * y)
print('x-y=', x - y)
# 等效于func(x=3,y=2),也等效于func(3,2)
func(y=2, x=3)
函数func()定义时形式参数的顺序是func(x, y),但是调用时实际参数的顺序确是func(y = 1, x = 2)。这是因为Python语言中提供了一种关键字参数的机制,可以给开发者提供更大的灵活性。
四、函数返回值
函数的返回值是函数执行完成后,系统根据函数的具体定义返回给外部调用者的值。
def func(x, y):
print('x+y=', x + y)
print('x*y=', x * y)
print('x-y=', x - y)
# 等效于func(x=3,y=2),也等效于func(3,2)
func(y=2, x=3)
print(func(3,2))
以上可以看出如果编写的函数中没有return的话就会返回None
以下是返回值的使用方法,其就是一个数
# 函数定义
def add(x, y):
print('x+y=', x + y)
return x + y
# 函数调用
result = add(y=1, x=2)
print(result)
在Python语言中,函数也可以有多个返回值
# 函数定义
def add(x, y):
print('x+y=', x + y)
print('x*y=', x * y)
return x + y, x * y
# 函数调用
a, b = add(y=1, x=2)
print(a, b)
注意: 返回值和接收变量的对应关系,是按照顺序一一对应的
五、函数分类
1.内置函数
内建函数是Python语言内置的函数,因此不需要导入任何函数库即可直接调用,常用的内建函数如图所示。
具体的内置函数可以通过访问 内置函数 — Python 3.10.4 文档 进行查看。
以下是内建函数abs()的调用过程及内建函数max()的调用。
abs(99)
abs(-99)
max(1, 6)
max(-1, 0, 4, 3)
abs()是绝对值函数。
内建函数max()可以同时返回多个数值的最大值,而其他编程语言中的类似函数一般只能接收两个变量。可见Python语言中内建函数的功能很强大。
Python语言常用的内建函数还包括数据类型转换函数,以下代码演示了常用类型转换函数的方法。
print("int('12'):", int('12'))
print("int(12.3):", int(12.3))
print("float('12.3'):", float('12.3'))
print("str(1.23):", str(1.23))
print("str(100):", str(100))
print("bool(1):", bool(1))
print("bool(''):", bool(''))
输出如下:
int('12'): 12
int(12.3): 12
float('12.3'): 12.3
str(1.23): 1.23
str(100): 100
bool(1): True
bool(''): False
注:在Python语言中,还可以把函数名赋给一个变量,相当于给这个函数起了一个“别名”,如下代码所示。
a = abs print(a(-1))
注:abs没有小括号,因此加了小括号相当于调用函数了。
2.自定义函数
发者可以根据实际需要自定义函数。函数自定义完成后,开发者可以在其他代码处通过函数名调用。
# 自定义函数
#打印传入字符串
def print(str):
print(str)
# 调用自定义函数
print("调用")
print("再次调用")
注:在Python语言中,内建函数可以直接使用,第三方函数需要使用import命令导入相应的库才能使用。对于自定义函数,其定义和调用可以在同一个文件中,也可分离成不同的文件。
导入方法:
from test import hello
hello()
函数的定义和调用不在一个文件的情形。首先,将hello()函数定义好并保存为test.py文件,然后使用Python语言的import指令“from test import hello”将该文件导入,可以调用hello()函数了。导入时需要注意test是文件名并且不含.py扩展名。
六、函数的参数
1.参数种类
函数参数分为可变类型和不可变类型,其调用结果是不同的。
(1)可变类型:类似c++的引用传递,如列表、字典等。如果传递的参数是可变类型,则在函数内部对传入参数的修改会影响到外部变量。
(2)不可变类型:类似c++的值传递,如整数、字符串、元组等。如果传递的参数是不可变类型,则在函数内部对传入参数的修改不会影响到外部变量。
不可变类型参数实例:
def change_int(a):
a = 10
b = 2
change_int(b)
print(b) # 结果是2
可变类型参数实例:
def change_int(my_list):
"修改传入的列表"
my_list.append([1, 2, 3])
print("函数内修改后的变量:", my_list)
my_list = [10, 20, 30]
change_int(my_list)
print("函数外变量的值:", my_list)
- 在定义函数时,开发者把参数的名字和位置确定后,函数的接口定义就完成了。
- Python语言的函数定义非常简单,但灵活度却非常大。
- 函数定义中可能包含多个形参,因此函数调用中也可能包含多个实参。
- 想让函数传递实参的方式有很多,可使用位置实参,要求传入参数和定义参数的顺序相同;也可使用关键字实参,每个实参都由变量名和值组成
2.位置参数
调用函数时,Python语言必须将函数调用中的每个实参都关联到函数的相应形参。最简单的关联方式是基于实参的顺序,这种关联方式被称为位置实参。
def describe_student(person_name, student_age):
print("my name is ", person_name)
print(person_name + "is" + student_age + "years old")
describe_student('Hong', '18')
Python语言将按顺序将函数调用中的实参关联到函数定义中相应的形参。但要注意的是,在使用位置实参来调用函数时,如果实参的顺序不正确,结果就会出错。
3.默认参数
编写函数时,可给每个形参指定默认值。在调用函数时,如果给形参提供了实参,Python语言将使用指定的实参值;否则,将使用形参的默认值。给形参指定默认值后,可在函数调用中省略相应的实参。使用默认值可简化函数调用,还可清楚地指出函数的典型用法。
开发者可以把第二个参数student_age的默认值设定为18,这样,当开发者调用describe_student(Hong)时,相当于调用describe_student(Hong,18) ,如下代码所示。
def describe_student(person_name, student_age='18'):
print("my name is ", person_name)
print(person_name + "is" + student_age + "years old")
describe_student('Hong')
describe_student('Hong', '18')
要注意的是,设置默认参数时,
必选参数在前
,默认参数在后
,否则Python语言的解释器会报错。使用时要牢记一点,默认参数必须指向不可变对象,否则会出现错误(可以用None这个不可变对象来解决报错问题)。
4.不定长参数
在Python语言中,函数还可以定义不定长参数,也叫可变参数。给定一组数字a,b,c……,请计算a+b+c+ ……,要定义出这个函数,必须确定输入的参数。开发者可以把a,b,c……作为一个list或tuple传进来。
def calc(numbers):
sum = 0
for n in numbers:
sum = sum + n
return sum
print(calc([2, 3,4])) # 结果是9
print(calc([2, 3, 4,5])) # 结果是14
在Python语言中,可以在函数参数前面添加“*”号把该参数定义为不定长参数;可以看出,不定长参数的使用使得calc()函数定义和调用都变得简洁,实例如下所示:
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n
return sum
print(calc(2, 3, 4,5))
print(calc())
num = [2, 3,4]
print(calc(*num))
5.关键字参数
关键字实参是传递参数时使用“名称–值”对的方式,在实参中将名称和值关联起来。让开发者无需考虑函数调用中的实参顺序,清楚地指出了函数调用中各个值的用途。其有扩展函数的功能。
6.命名关键字参数
如果要限制关键字参数的名字,可以用命名关键字参数。和关键字参数**kw不同,如果没有可变参数,命名关键字参数就必须加一个“”号作为特殊分隔符。如果缺少“”,Python语言解释器将无法识别位置参数和命名关键字参数。
注意:
*表示不定长参数
**表示不定长的关键字参数
7.参数组合
在Python语言中定义函数,开发者可以组合使用这些参数(必选参数、默认参数、可变参数、关键字参数和命名关键字参数)。注意参数定义是有顺序的。
定义的顺序
必须是:必选参数、默认参数、可变参数、命名关键字参数和关键字参数
。比如要定义一个函数,包含上述若干种参数,如下代码所示。
def func(a, b, c=0, *args, **kw):
print('a=', a, 'b=', b, 'c=', c, 'args=', args, 'kw=', kw)
print(func(1, 2))
# 输出结果:a= 1 b= 2 c= 0 args= () kw= {}
print(func(1, 2, c=3))
# 输出结果:a= 1 b= 2 c= 3 args= () kw= {}
print(func(1, 2, 3, 'a', 'b'))
# 输出结果:a= 1 b= 2 c= 3 args= ('a', 'b') kw= {}
print(func(1, 2, 3, 'a', 'b', x=4))
# 输出结果:a= 1 b= 2 c= 3 args= ('a', 'b') kw= {'x': 4}
args = (1, 2, 3, 4)
kw = {'x': 5}
print(func(*args, **kw))
# 输出结果:a= 1 b= 2 c= 3 args= (4,) kw= {'x': 5}
ARGS:MIAN函数中args参数,args[]在命令行运行时输入的参数,因为参数可以为多个,所以要用数组来存。
七、函数式编程
- 函数式编程是一种编程范式,是面向数学的抽象,其将计算描述为一种表达式求值。
- 函数式编程中的“函数”不是指计算机中的函数,而是指数学中的函数,即自变量的映射。
- 函数式编程的一个特点就是,允许把函数本身作为参数传入另一个函数,还允许返回一个函数。
- Python语言对函数式编程提供部分支持。由于允许使用变量,所以说Python语言不是纯函数式编程语言。
1.高阶函数
接受函数为参数,或者把函数作为结果返回的函数称为高阶函数。
例如,若要根据单词的长度排序,只需把len函数传给key参数。
fruits=['strawberry','fig','apple','cherry','raspberry','banana']
print(sorted(fruits,key=len))
# 输出结果如下:
# ['fig', 'apple', 'cherry', 'banana', 'raspberry', 'strawberry']
在函数式编程范式中,最为人熟知的高阶函数有map、filter、reduce 和apply。其中,apply函数在Python2.3中标记为过时,在Python3已移除。
2.匿名函数
所谓匿名函数,即
不再使用def语句
这样标准形式定义的函数。Python语言经常使用lambda
来创建匿名函数。lambda 只是一个表达式,函数体比def定义的函数体要简捷。lambda函数的语法如下所示。关于lambda的深入理解
lambda [arg1,arg2,....argn]]:expression
例如:
sum = lambda arg1, arg2: arg1 + arg2
print(sum(1, 2)) # 结果是:3
代码会通过sum()函数即实现了调用lambda函数的功能。