【Think Python】Python笔记(六)有返回值的函数

(一)返回值

调用一个有返回值的函数会生成一个返回值;通常将这个返回值赋值给变量或者作为表达式的一部分;

def area(radius):
    a = math.pi * radius**2
    return a
  • return语句意味着:立即从该函数返回,并且使用接下来的表达式作为返回值;返回值可以是任意复杂的;
  • 在一个有返回值的函数中,最好保证程序执行的每一个流程都最终碰到一个return;【充分考虑好每一种分支情况】

(二)增量式开发(incremental development)

  • 随着函数越来越复杂,调试的时间会越来越多;为了应对负载的程序,可以尝试增量式开发;
  • 增量式开发的目标,是通过每次只增加和测试少量代码,来避免长时间的调试;
  • 比如,在写一个函数的时候,可以先写一下这个函数的函数头和形参,函数体可以用pass或者其他的return语句进行代替;当这个函数头可以运行的时候,再往函数体中增加代码;
  • 当然上面的只是一个简单的类比,只是一种简单的思路:当想要实现一个功能的时候,尤其是复杂的功能,不要想着一步到位,可以将这个功能进行分解,或者先实现一个框架,之后再逐步完善细节;
  • 增量式开发的关键:
    1. 从一个能运行的程序开始,并且每次只增加少量改动。无论你何时遇到错误,都能够清楚定位错误的源头;
    2. 使用临时变量存储中间值,这样能显示并检查它们;
    3. 一旦程序能够正确运行,就要删除一些脚手架(scaffolfing)代码;或者将多条语句组合成为复合表达式,当然,前提是不影响程序的可读性;

(三)组合

  • 我们可以从一个函数的内部调用另一个函数;
  • 一些临时变量对于开发很有用,但是一旦程序正确运行了,我们可以通过合并函数调用,使得程序更加简洁;

(四)布尔函数

  • 这种类型的函数可以返回布尔类型(booleans),通常对于隐藏函数内部的复杂测试代码非常有用;
  • 布尔函数通常用于条件语句中;
def is_divisible(x, y):
	if x%y == 0:
        return true;
    else:
        return false;

==的返回值是Boolean类型,可以直接使用这个来简化上面的代码:

def is_divisible(x, y):
    return x % y == 0

(五)再谈递归

到目前为止,虽然学到的知识Python中很小的一个子集,但是实际上,这已经是一个完备的编程语言,这意味着任何能够被计算的东西都可以用这个语言表达;

  • 使用递归计算阶乘:
def factorial(n):
    if n == 0:
        return 1
    else:
        return n * factorial(n-1)
  • 程序的执行过程:【假如n == 3】

  • 堆栈图:

(六)信任之跃【一种阅读代码的方法】

  • 跟随程序的执行流程读代码,是一种方法,但是可能很快就会变得错综复杂;
  • 另一种方法:当遇到一个函数的时候,不去跟踪函数的执行流程,而是假设这个函数正确运行并且返回了正确的结果;
  • 事实上,使用内建函数的时候已经使用的了这种方法,我们总是假设,这个内建函数的执行是正确的;
  • 使用递归函数也是一样的,我们不再顺着执行流程,而是假设每次递归都能正确执行;

(七)斐波那契数列【递归】

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacii(n-1)+fibonacci(n-2)

(八)检查数据类型

  • 上面的函数中,当输入的参数是一个非整数的时候,这时候,递归将无限进行下去,因为没有边界;
  • 我们需要检查传入的参数是不是我们所希望的类型;
  • 我们使用内建函数isinstance来验证实参的类型:
def factorial(n):
    if not isinstance(n, int):
		print('Factorial is only defined for integers.')
        return None
    elif n<0:
         print('Factorial is not defined for negative integers.')
         return None
    elif n == 0:
        return 1
    else:
        return factorial(n-1)*n
  • 上面的方法有时候称之为“监护人(Guardian)模式;通过设置监护人,保证后面的代码不会出现错误;
  • 当然还有更加灵活的方式:抛出异常

(九)调试

将一个大程序分解为若干较小的函数,为程序的调试生成的自然的检查点;当一个程序不能如预期运行的时候,需要考虑的情况:

  1. 该函数获取的实参有问题,违反先决条件;
  2. 该函数有些问题,违反后置条件;
  3. 返回值或者使用方法有问题;

实参问题

为排除这种可能性,可以在函数的开始增加一条print语句,打印形参的值或者类型

函数问题

如果函数的形参没有问题,则在函数的return之前,打印结果、返回值;考虑用一些简单的值调用这个函数;

调用问题

要确保返回值被正确地使用;

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章