4.2.6 函数的返回值

函数作为一种模块构件,它与其他模块如何协作、交换信息?我们已经知道,通过函数 调用时的参数传递,可以实现从函数外部向函数内部输入数据。本节讨论函数向外部输出信 息的问题。

在数学中,函数是从定义域到值域的映射,亦即从自变量计算出函数值。编程语言中的 函数原本就是数学函数的模仿物,自然也可以计算出一个结果输出给函数调用者,我们称函 数输出的计算结果为函数的返回值(returned value)。

在前面几章中,我们已多次使用过具有返回值的内建函数和库函数。例如,内建函数 len() 能够接收一个字符串,然后返回该字符串的长度;数学库中的函数 math.sqrt()接收一个 数值,并返回该数值的平方根。我们还看到,带有返回值的函数基本上可以当作一个值来看 待,可以和其他数据一起进行运算,构成表达式。例如:

  1. (-b + math.sqrt(b*b 4*a*c)) / 2*a
  2. range(len("hello"))
  3. x = input("Enter a number:")

如何自定义带有返回值的函数呢?Python 语言提供了一条 return 语句用于从函数返 回值,用法如下:

  1. def f():
  2. ...
  3. return <表达式 1>, ..., <表达式 n>
  4. ...

其语义是:当 Python 在执行函数 f()时,一旦遇到 return 语句,就终止执行函数,并将 控制返回到函数调用点,同时将各表达式的计算结果返回给调用者。

与 Python 内建函数、库函数一样,带返回值的用户自定义函数可以像一个普通的数据 值一样使用,例如用在表达式中参加运算(当然要求数据类型合法)或者作为赋值语句的右 端为变量赋值。

例如,下面的函数实现了数学函数 f(x) = x2 的功能:

  1. >>> def sq(x):
  2. return x * x
  3. >>> sq(2)
  4. 4
  5. >>> print sq(3) + 1
  6. 10
  7. >>> a = 4
  8. >>> b = sq(a)
  9. >>> print b
  10. 16

再看一个例子,下面的 dist()函数能够计算平面上两点间的距离。我们将平面上的点 表示为由横坐标和纵坐标组成的元组(x,y)。根据数学中的距离公式,并利用上面的 sq() 函数,可以写出如下代码:

  1. >>> import math
  2. >>> def dist(u,v):
  3. d = math.sqrt(sq(v[0]-u[0])+sq(v[1]-u[1])) return d
  4. >>> dist((0,0),(4,0))
  5. 4.0
  6. >>> dist((0,0),(0,5))
  7. 5.0
  8. >>> dist((0,0),(1,1))
  9. 1.4142135623730951
  10. >>> dist((1,2),(3,4))
  11. 2.8284271247461903

如果函数返回值有多个,那么调用者需要使用多个变量来接收函数的返回值。例如下面 的函数 headtail()对一个列表取出头尾元素:

  1. >>> def headtail(list):
  2. return list[0], list[len(list)-1]
  3. >>> headtail([1,2,3,4,5])
  4. (1, 5)

调用 headtail 这种返回多个值的函数时,调用者可以利用多变量同时赋值语句来接

收多个返回值,也可以只用一个变量来接收返回值,因为函数返回的“多个值”实际上构成

一个元组。

  1. >>> h,t = headtail([1,2,3,4,5])
  2. >>> print h,t
  3. 1 5
  4. >>> v = headtail([1,2,3,4,5])
  5. >>> v
  6. (1, 5)

函数中的 return 语句通常都出现在函数的末尾,因为函数一般都是执行完所有步骤 之后才能得出计算结果并返回。然而,有时我们希望在函数到达末尾之前就终止执行并返回, 例如当函数检测到不正确的数据时就没有必要继续执行,因为计算下去只能带来错误结果。 下面这个例子检查用户输入(要求是正数),如果不满足要求则退出函数,否则对用户数据 进行处理。代码如下:

  1. >>> def f(x):
  2. if x <= 0:
  3. print "Positive numbers only, please."
  4. return
  5. y = x ** 3
  6. return y
  7. >>> f(0)
  8. Positive numbers only, please.
  9. >>> f(2)
  10. 8

最后要说明一点,在 Python 中,任何函数无论是否包含 return 语句,总是要返回一个值的。如果包含 return 语句,自然就返回程序员指定的值;如果不含 return 语句, 则函数总是返回一个称为 None 的特殊对象。如果编程时忘记在函数中用 return 语句返回 值,而调用处又企图使用返回值,则可能出错。例如,假设上面定义的 dist()函数忘了最 后的 return 语句,我们看会带来什么后果:

  1. >>> import math
  2. >>> def dist(u,v):
  3. d = math.sqrt(sq(v[0]-u[0])+sq(v[1]-u[1]))
  4. >>> print dist((0,0),(2,2))
  5. None
  6. >>> print 2 + dist((0,0),(2,2))
  7. Traceback (most recent call last):
  8. File "<pyshell#42>", line 1, in <module> print 2 + dist((0,0),(2,2))
  9. TypeError: unsupported operand type(s) for +: 'int' and 'NoneType'

可见调用 dist()后得到的结果是 None;如果将这个 None 用于表达式中(例中是与 2 相 加)则可能出错,因为对 None 对象并没有定义加法运算。对初学 Python 编程的人来说, 这是容易犯错的地方,所以一定要注意返回值。