函数基础

函数是为了实现代码重用而提供的一种基本的程序结构,它由多个语句组成,负责完成某项特定任务,具有相对的独立性。函数能提高代码代码重用(同时减少代码冗余),同时也提供了一种将一个系统分割为定义完好的不同部分的工具。

我们在前面已经使用过 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)
函数参数传递