函数是为了实现代码重用而提供的一种基本的程序结构,它由多个语句组成,负责完成某项特定任务,具有相对的独立性。函数能提高代码代码重用(同时减少代码冗余),同时也提供了一种将一个系统分割为定义完好的不同部分的工具。
我们在前面已经使用过 Python 标准库提供的各种函数了,如内置的 print()、input()、range()、len()、list(),等等,math 模块内的 sin()、ceil() 等。
本章将介绍如何在 Python 中编写用户自定义函数。
函数定义#
函数定义就是对用户自定义函数的定义。函数通过 def 语句定义,该语句创建一个函数对象并将其赋值给函数名(相当于一个变量),其形式为:
def function_name(arg1, arg2,..., argN):
...
return value
def 语句包含头部和一段紧随其后的代码块。其中头部定义了被赋值函数名 function_name,并在圆括号中包含了零个或更多的参数。头部后的代码块通常包含多个缩进的语句,即为函数体。函数体常常包含一个可选的 return 语句。函数定义并不会执行函数体。
每次调用函数的时候,括号中传入的对象将赋值给头部的参数,然后执行函数体。
示例#
示例 1:打印欢迎信息#
以下是一个非常简单的示例函数,它对传入的名称打印欢迎信息:
def welcome(name):
print('您好,' + name + '!')
# 调用函数
welcome('小明') # 您好,小明!
welcome('行者') # 您好,行者!
示例 2:计算两数之和#
以下又是一个非常简单的示例函数,它计算并返回两数之和:
def add(a, b):
return a + b
# 调用函数
num = add(3, 6)
print(num) # 9
示例 3:寻找序列的交集#
以下定义的 intersect 函数可以计算两个序列的交集:
def intersect(s1, s2):
result = []
for x in s1:
if x in s2:
result.append(x)
return result
# 以上 5 行也可以使用列表推导式简化为下面一行
# return [x for x in s1 if x in s2]
list1 = [2, 3, 4, 6, 9]
list2 = [3, 4, 5, 6, 7]
list3 = intersect(list1, list2)
print(list3) # [3, 4, 6]
Python 中的多态#
在调用前面定义的 add() 和 intersect() 函数时,我们可以向他们传入不同类型的参数。如下所示:
print(add(3, 6)) # 9
print(add(3, 6.2)) # 9.2
print(add('Hello, ', 'world!')) # Hello, world!
print(add([4, 6], [True, 5])) # [4, 6, True, 5]
print(intersect((2, 1), (2,))) # [2]
print(intersect([2, 1], {2, 5, 1})) # [2, 1]
print(intersect('abcd', 'cow')) # ['c']
这里 add(3, 6) 执行的是加法,而 add('Hello, ', 'world!') 执行的则是字符串拼接。这种依赖类型的行为称为多态,多态能根据被操作类型的不同执行不同的操作。
Python 作为一种动态类型的语言,对多态具有良好的支持,这极大地提高了程序的简洁性和灵活性。
如前面定义函数那样,并不用去声明参数的类型(静态类型语言必须显式声明参数的类型),这些函数会尝试对传递给他们的参数进行操作。但是,如果我们传入的参数类型不支持函数体所进行的操作,Python 会自动检测出不匹配,并抛出一个异常。
print(intersect(5, [2, 4, 5]))
# TypeError: 'int' object is not iterable
返回值#
从前面的示例可知,在函数体内通过 return 语句为函数指定返回值。该语句用于退出函数;当其后有表达式时,将返回该表达式的值;当其后没有表达式时,默认返回 None。当没有 return 语句,函数执行完毕退出也返回 None。
函数内可以同时包含多个 return 语句,但只有一个能被执行:
def is_odd(num):
if num % 2 != 0:
return True
else:
return False
print(is_odd(13)) # True
print(is_odd(14)) # False
当需要函数有多个返回值时,可以将这些返回值打包为元组:
def mid_point(a, b):
x = (a[0] + b[0]) / 2.0
y = (a[1] + b[1]) / 2.0
return x, y
x, y = mid_point((0, 0), (14, 16)) # 解包
print((x, y)) # (7.0, 8.0)