Python函数返回值的重要性及如何优化代码测试

[id_1260736854]

Python函数返回值的重要性及如何优化代码测试

...print(a+b)

...

>>>b=add(1,2)

>>>b

>>>bisNone

True

你会发现 b 的返回值实际上为 None。若你所写的函数没有返回语句,它依然会返回某些东西。并且,每个函数都应当返回一个有用的值,这样测试起来会更加便捷。毕竟,你所写的代码是应该能够被测试的。

想一想,测试上述的 add 函数会是多么困难。依照这个概念,我们应当如此来编写代码:

打开名为“foo.txt”的文件并以只读模式进行操作,将其赋值给变量 input_file 。

forlineininput_file:

如果 line 进行了去除空白字符操作后,再转换为小写形式,并且以“cat”结尾,那么就满足条件。

用这些线条做一些有用的事情。 这些线条可以被用来做一些有意义的事。 利用这些线条去做些有益的事情。 把这些线条用于做一些有用的举动。 借助这些线条去进行一些有用的操作。 用这些线条开展一些有用的活动。 以这些线条为基础做一些有用的事儿。 凭借这些线条去做一些有用的行为。 利用这些线条去实施一些有用的举措。 用这些线条去进行一些有用的实践。 借助这些线条去展开一些有用的动作。 以这些线条为凭借做一些有用的事。 凭借这些线条去从事一些有用的活动。 利用这些线条去展开一些有用的行为。 以这些线条为依托做一些有用的事。 借助这些线条去进行一些有用的实践。 以这些线条为基础开展一些有用的活动。 凭借这些线条去实施一些有用的动作。 利用这些线条去从事一些有用的行为。 以这些线条为凭借展开一些有用的实践。 以这些线条为依托开展一些有用的动作。 以这些线条为基础从事一些有用的行为。

如果一行被去除空白字符后转换为小写并以“cat”结尾,那么这一行能够工作,原因是每个字符串方法,像 strip()、lower()、endswith(),都会返回一个字符串作为调用函数的结果。

当给定函数没有返回值时,有一些常见的原因:

它做的只是一些与 I / O 相关的事,例如把一个值保存到数据库里。我无法返回任何有价值的东西。

我不同意。如果操作顺利完成,函数可以返回True。

“我们修改了其中一个参数,将其用作参考参数。”

这里有两点需注意。其一,要尽最大努力避免这种做法。其二,这种做法用好了会令人惊讶,用不好则非常危险。

其次,若这样做不可行,且复制某个参数的成本过高,那么你可以回到上一条建议。

“我需要返回多个值。单独返回一个值是没有意义的。”

可以使用元组返回多个值。

总是返回一个有用的值,调用者总是可以自由地忽略它们。

函数长度

读一个 200 行的函数,然后说出它的作用,你会有怎样的感受呢?

函数的长度会对可读性产生直接影响,进而影响可维护性。因此,要让你的函数保持简短。50 行是一个较为随意的数字,在我看来是比较合理的。你编写的大部分函数都应该尽量短一些。

如果一个函数遵循单一功能原则,那么它很有可能是比较短的。如果它是纯函数或者是幂等的(下面会进行讨论),它也有可能是短的。

如果函数比较长,那应该采取什么措施呢?可以进行重构。重构能够改变程序的结构,同时不会对其行为产生影响。

从一个长函数里提取出几行代码,然后将这些代码变成自己的一个函数。这是能够缩短长函数的最为快速且最为常见的一种方式。

你给所有这些新函数都取了合适的名称,所以生成的代码读起来会更容易。

幂等和函数纯度

幂等函数不管被调用多少次,只要给定的是相同的参数集,就总是会返回相同的值。

结果与非局部变量、参数的可变性以及来自任何 I/O 流的数据无关。以下这个 add_three(number)函数属于幂等函数:

def add_three(number):
    """Return *number* + 3."""
    return number + 3

一个人不管调用 add_three(7)多少次,答案始终是 10。这里有一个非幂等函数:

defadd_three():

输入一个数字,将其赋值给变量 number,即 number = int(input('Enter a number:'))

returnnumber+3

这个函数的返回值与 I / O 相关,也就是和用户输入的数字有关。每次调用 add_three()都会得出不一样的值。

如果它被调用两次,用户能够在第一次输入 3,然后第二次输入 7,这样就可以分别调用 add_three()函数,从而得到 6 和 10。

在现实中有一个关于幂等性的例子,那就是在电梯前点击“向上”按钮。当第一次按时,电梯会接收到你要上去的“通知”。由于按按钮具有幂等性,所以即便反复按它,也不会产生什么影响。最终的结果是相同的。

为什么幂等很重要?

可维护性很重要,幂等函数容易测试。因为当使用相同参数时,幂等函数总是会返回相同的结果。

测试只是检查通过不同调用所返回值的预期值。这些测试速度很快,这在单元测试中是一个重要且常被忽视的问题,这一点更为重要。

在处理幂等函数时,重构这件事做起来很容易。不管在函数之外以何种方式更改代码,只要用相同的参数去调用它,得到的结果始终是相同的。

什么是纯函数?

在函数编程领域中,若一个函数具备幂等性且不存在可观察到的副作用,那么它会被认定为纯函数。并且,函数外部的任何因素都不会对该值产生影响。

然而,这并不意味着函数无法影响非局部变量或者 I/O 流这类事情。比如,倘若上面 add_three(number)的幂等版本在返回结果之前把结果给打印出来了,那么它依然被视作是幂等的。这是因为当它对 I/O 流进行访问时,这种访问与从函数返回的值没有关联。

调用 print() 具有一个副作用。它除了会有返回值之外,还会与程序的其他部分或者系统本身进行一些交互。

让我们把我们的 add_three(number)这个示例进一步推进。我们能够编写以下的代码片段,用以确定调用 add_three(number)的次数。

add_three_calls=0

defadd_three(number):

"""Return*number*+3."""

globaladd_three_calls

print(f'Returning{number+3}')

add_three_calls+=1

returnnumber+3

defnum_calls():

获取*add_three*被调用的次数。

returnadd_three_calls

我们正在向控制台进行打印(这是一个副作用),同时也在修改一个非局部变量(这是另一个副作用)。然而,因为这两个行为都不会对函数的返回值产生影响,所以它依然是幂等的。

纯函数不存在副作用。它不会借助任何“外部数据”来计算值,并且除了进行计算并返回该值之外,它与系统或程序的其他部分都没有交互行为。所以,尽管我们新的 add_three(number)定义依然是幂等的,但它已不再是纯函数了。

纯函数不会有日志语句或者进行 print ( ) 的调用。它们不会运用数据库或者建立互联网连接。它们不会去访问或者修改那些非局部的变量。它们也不会调用任何其他非纯的函数。

简而言之,它们无法做到爱因斯坦在计算机科学环境中所说的“远距离幽灵般的行动”。它们不会对程序或系统的其余部分进行任何方式的修改。

在编写 Python 代码时所采用的命令式编程中,它们属于所有函数里最为安全的那类函数。

它们很容易进行测试和维护。相比只是幂等函数而言,更为重要的是,对它们进行测试基本上能够和执行它们的速度一样快。

测试本身较为简单。它没有进行数据库连接的模拟,也没有其他外部资源的模拟。同时,不需要进行代码的安装,并且之后也没有需要清理的东西。

明确来讲,幂等性以及纯函数仅仅是一种期望,并非是必须要具备的。这意味着,因为其具有诸多好处,我们或许会期望仅仅去编写纯函数或者幂等函数,然而这在实际中是不现实的。

重要的是,我们要开始有意识地写代码,以隔离副作用和外部依赖性。这样会让我们编写的每一行代码都更易于被测试。

原文链接:

— 完 —

加入社群

量子位 AI 社群开始进行招募。欢迎那些对 AI 怀有兴趣的同学,在量子位的公众号(QbitAI)的对话界面中,回复关键字“交流群”,这样就能获取入群的方式。

此外,量子位有专业细分群,包括自动驾驶、CV、NLP、机器学习等领域。这些专业细分群正在进行招募,招募对象是正在从事相关领域工作的工程师以及研究人员。

在量子位公众号(QbitAI)的对话界面中,若要进入专业群,需回复关键字“专业群”,这样就能获取入群方式。(需知专业群审核较为严格,还望大家予以谅解)

诚挚招聘

量子位正在进行编辑/记者的招募工作,其工作地点位于北京中关村。我们期待富有才气且充满热情的同学能够加入我们!若想了解相关细节,可在量子位公众号(QbitAI)的对话界面中,输入“招聘”这两个字。

量子位QbitAI · 头条号签约作者

վ'ᴗ' ի 追踪AI技术和产品新动态

你可能想看:
« 上一篇
下一篇 »

相关推荐

python爬虫教程PDF,Python爬虫书PDF

2026年09月02日

31阅读

外国教程python,python编程教学视频

2026年09月02日

25阅读

python简明教程沈洁元,python详细基础教程

2026年09月02日

21阅读

python库包教程,python 包

2026年09月02日

27阅读

python教程大全集,python教程600集

2026年09月02日

27阅读

python入门教程完整版,python零基础入门全套教程视频

2026年09月02日

23阅读