python 函数和范围界定

1,017 阅读5分钟

持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第26天,点击查看活动详情

python 函数、范围和抽象

到目前为止,我们已经引入了数字、赋值、输入/输出、比较和循环构造。这个Python子集有多强大?在理论意义上,它和你需要的一样强大,也就是说,它是图灵完备的。这意味着,如果一个问题可以通过计算来解决,那么它只能使用你已经看到的那些语言机制来解决。

但是,仅仅因为某些事情可以做,并不意味着它应该被完成!虽然原则上任何计算都可以仅使用这些机制来实现,但这样做是非常不切实际的。在上一章中,我们研究了一种算法,用于查找正数平方根的近似值,请参见图

image.png

这是一段合理的代码,但它缺乏一般的实用性。它仅适用于分配给变量 x 和 epsilon 的值。这意味着,如果我们想重用它,我们需要复制代码,可能编辑变量名称,并将其粘贴到我们想要的位置。我们不能轻易地在其他更复杂的计算中使用这种计算。此外,如果我们想计算立方根而不是平方根,我们必须编辑代码。如果我们想要一个同时计算平方根和立方根的程序(或者计算两个不同地方的平方根),那么该程序将包含多个几乎相同的代码块。

图 4-2 调整了图 4-1 中的代码,以打印 x1 的平方根和 x2 的立方根之和。代码可以工作,但它并不漂亮。

image.png

程序包含的代码越多,出错的可能性就越大,代码就越难维护。例如,想象一下,在对等搜索的初始实现中存在错误,并且在测试程序时发现了该错误。将实现修复在一个地方并且不注意到其他地方需要修复的类似代码非常容易。

幸运的是,Python提供了几种语言特性,使得泛化和重用代码变得相对容易。最重要的是功能。

函数和范围界定

我们已经使用了许多内置函数,例如图 4-1 中的 max 和 abs。程序员能够定义然后使用自己的函数,就好像它们是内置的一样,这是便利性的质的飞跃。

函数定义

在Python中,每个函数定义都是函数的form25 def名称(形式参数列表):

image.png

例如,我们可以定义代码

image.png

def是一个保留字,告诉Python一个函数即将被定义。函数名称(在此示例中max_val)只是用于引用函数的名称。PEP 8 约定是函数名称应全部为小写,单词之间用下划线分隔,以提高可读性。

函数名称后面的括号内的名称序列(在本例中为 x,y)是函数的形式参数。使用函数时,形式参数(如在赋值语句中)绑定到函数调用(也称为函数调用)的实际参数(通常称为参数)。例如,调用

max_val(3,4)

将 x 绑定到 3,将 y 绑定到 4。

函数体是Python代码的任何一段.27 但是,有一个特殊的语句 return,只能在函数的主体中使用。

函数调用是一个表达式,与所有表达式一样,它具有一个值。该值由调用的函数返回。例如,表达式 max_val (3, 4) *max_val (3,2) 的值为 12,因为第一次调用 max_val 返回 int 4,第二次调用返回 int 3。请注意,执行返回语句将终止函数的调用。

要概括,当调用函数时

1.计算构成实际参数的表达式,并将函数的形式参数绑定到结果值。例如,调用max_val(3+4, z) 会将形式参数 x 绑定到 7,并将形式参数 y 绑定到执行调用时变量 z 具有的任何值。

  1. 执行点(要执行的下一条指令)从调用点移动到函数体中的第一个语句。

  2. 执行函数体中的代码,直到遇到任何一个 return 语句,在这种情况下,返回后面的表达式值将成为

函数调用,或者没有更多要执行的语句,在这种情况下,函数返回值 None。(如果返回后没有表达式,则调用的值为 None。28

  1. 调用的值是返回的值。5. 调用后立即将执行点传输回代码。

参数允许程序员编写的代码不是访问特定对象,而是访问函数调用方选择用作实际参数的任何对象。这称为 lambda 抽象。

图 4-3 包含一个具有三个形式参数的函数,并返回一个值(称为 result),使得 abs(结果**幂 -x)> = epsilon。

image.png

图 4-4。包含可用于测试find_root是否按预期方式工作的代码。测试函数test_find_root的长度与查找根本身的长度大致相同。对于没有经验的程序员来说,编写测试函数似乎常常是浪费精力。然而,有经验的程序员知道,编写测试代码的投资往往会带来巨大的回报。在调试期间,坐在键盘前一遍又一遍地将测试用例键入 shell(找出程序无法正常工作的原因,然后修复它的过程)当然比更好。请注意,由于我们调用的是长度为三的三个元组(即值序列)的 test find 根,因此一个调用将检查 27 个参数组合。最后,由于test_find_root检查find_root是否返回了适当的答案并报告结果,因此它使程序员免于执行繁琐且容易出错的任务,即目视检查每个输出并检查其正确性。