2

我有时会忘记return result从一个函数:

def f(*args):
  # do stuff
  result = # an expression
  # oops forgot to return result

由于None在我的应用程序中是一个有效值,因此这不会在调用者中引发任何异常甚至任何警报。当然,我尽量小心。但我想知道是否有一些巧妙的方法可以警告我任何没有明确返回值的函数。

也许我可以通过我的代码运行一个正则表达式来找到这种情况。或者一些代码检查工具(希望在Windows环境下可用)。

我什至在考虑使用这样的装饰器:

def requires_return(func):
  def new_func(*args, **kwargs):
    result = func(*args, **kwargs)
    if result is None:
      print('Warning: {} may be missing a return statement'.format(func.__name__))
    return result

但这行不通,因为:

  1. 许多误报:每次函数实际返回None. None如果不在其他地方创建非常丑陋的代码,我就无法停止在我的应用程序中使用。

  2. 无论如何,为每个函数添加一个装饰器看起来超级丑陋。

请注意,我确实有故意没有return声明的功能。我倾向于保持一定的命名约定,这让我很容易区分它们。(具体来说,每个以 开头的函数都get_必须有一个 return 语句。)

4

4 回答 4

4

我建议不要养成这样做的习惯

def something():
    ...
    result = ...
    return result

相反,只需执行以下操作:

def something():
    ...
    return ...

除此之外,None默认返回是 99% 的有用功能。

于 2012-04-08T22:51:25.300 回答
4

简答

一言以蔽之:unittest

这不是您应该尝试使用生产代码解决的问题。一套好的测试将解决您的问题。

单元测试 101

您应该真正了解什么是单元测试,作为快速参考,请记住单元测试是关于测试您的 API。

还有一种称为TDD(测试驱动开发)的做法,即在实际代码之前编写测试的做法。所以程序员为一段不存在的代码编写测试,测试显然失败了,程序员去生产代码,编写他的函数,运行测试,如果测试通过,他继续。

一开始养成编写测试的习惯有点困难,但它确实有回报。

为什么在这里进行单元测试

我看不出通过正确的测试集怎么可能错过回报。

“由于None在我的应用程序中是一个有效值,这不会在调用者中引发任何异常甚至任何警报。”

返回None的作用是破坏您的 API。单元测试是解决这个问题的确切方法。

如何防止这个错误?

防止此错误的方法是使用TDD

如果你先编写测试,你有 99.9% 的把握在这个 bug 变成 bug 之前就发现它。

注意:我知道这不是您要寻找的答案,但单元测试是这里的正确工具。不使用result变量或将装饰器附加到每个函数都不会解决您的问题。

于 2012-04-08T23:33:16.063 回答
3

Pylint 有时会捕捉到这种错误。特别是如果您分配给result但从不使用它:

pylint zorg.py
************* Module zorg
W0612:  5:zorg: Unused variable 'result'

但是,它不会捕获您分段构建result然后忘记返回它的情况(因为那时变量不是“未使用”)。

但是,根据许多其他事情,pylint 通过其静态类型分析可能会捕获返回值的失败。

于 2012-04-08T22:58:20.037 回答
0

预防胜于治疗——这意味着你应该真正学会在必要时返回值的习惯。您也可以return statement直接使用而不是result = statement; return result.

于 2012-04-08T22:52:35.417 回答