程序员最近都爱上了这个网站  程序员们快来瞅瞅吧!  it98k网:it98k.com

本站消息

站长简介/公众号

  出租广告位,需要合作请联系站长

+关注
已关注

分类  

暂无分类

标签  

暂无标签

日期归档  

2023-05(1)

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

发布于2020-02-25 16:48     阅读(1072)     评论(0)     点赞(24)     收藏(1)


(一)返回值

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

def area(radius):
    a = math.pi * radius**2
    return a
  • 1
  • 2
  • 3
  • 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;
  • 1
  • 2
  • 3
  • 4
  • 5

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

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

(五)再谈递归

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

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

  • 堆栈图:

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

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

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

def fibonacci(n):
    if n == 0:
        return 0
    elif n == 1:
        return 1
    else:
        return fibonacii(n-1)+fibonacci(n-2)
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

(八)检查数据类型

  • 上面的函数中,当输入的参数是一个非整数的时候,这时候,递归将无限进行下去,因为没有边界;
  • 我们需要检查传入的参数是不是我们所希望的类型;
  • 我们使用内建函数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
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 上面的方法有时候称之为“监护人(Guardian)模式;通过设置监护人,保证后面的代码不会出现错误;
  • 当然还有更加灵活的方式:抛出异常

(九)调试

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

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

实参问题

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

函数问题

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

调用问题

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

发布了67 篇原创文章 · 获赞 2 · 访问量 6693


所属网站分类: 技术文章 > 博客

作者:进击的巨人

链接:https://www.pythonheidong.com/blog/article/233567/00bf7cf8b63d769db719/

来源:python黑洞网

任何形式的转载都请注明出处,如有侵权 一经发现 必将追究其法律责任

24 0
收藏该文
已收藏

评论内容:(最多支持255个字符)