为什么需要空函数


9

我开始学习python,我想知道为什么编程语言中需要空函数

例如在python中:

def empty_func():
    pass

即使在shell脚本中,也可以使用空函数空函数。

我的理解和问题:

  1. 为什么编程语言需要空函数?它是只是在玩编程语言还是真正重要的其他事情?

  2. 如果这是有目的的,那么谁能描述用例或给出使用空函数的真实示例?

  3. 还是有编程语言允许空函数的传统?


编辑(我从阅读答案中得到的信息):

  • 用于草绘算法或抽象函数
  • 对于提交表单,无需执行任何操作
  • 某些强制性操作的占位符

1
如果程序执行希望找到/使用它们,它们可以用作STUBS,但是您不想通过它们进行任何更改。
G.Rassovsky

Answers:


5

在Bourne系列的Shell语言中:,什么都不做的命令通常在两种情况下使用:

  • 占位符,表示某些需要强制命令的地方,例如

    while some_condtion
    do :
    done

    因为do需要至少一个命令。

  • 丢弃参数,但在参数列表内执行副作用,例如

    : ${myvar=foo}

我确定外壳专家可能还会知道其他应用程序:)

在Python(和其他语言)中,使用频率较低。当您实际上不想执行任何操作时,它可以用作高阶函数的参数。例如,假设您有一个提交表单的函数,并允许在提交完成后异步调用该函数:

def submit(callback=empty_func):
    ...

这样,如果callback未提供,提交仍将继续进行,但不会执行进一步的操作。如果使用None默认值,则必须显式检查回调是否为None,从而使代码混乱。


1

这取决于您在开发周期中所处的位置,但是有时在草拟算法时,您想对复杂的块进行抽象而不立即实施它们。

def full_algo():
  init_stuff()
  process_stuff()
  ...

您知道init_stuff它是如何工作的,它在您脑海中非常简单,但是您并不是真的需要它,因此您将其声明为空函数。它将使您的代码得以编译和运行,而无需担心细节问题。

已发布应用程序的另一个用途是使用继承时。假设您有一个大型类,用于定义平台特定代码的行为。您可能最终会得到类似于以下内容的逻辑:

init_filesystem();
access_files();
release_filesystem();

该代码可在许多平台上运行,但是某些平台可能不需要文件系统初始化。然后,您的继承将如下所示(在C ++中为虚拟值= 0,仅意味着派生类必须实现这些方法):

class FileSystem{
  virtual void init_filesystem() = 0;
  virtual void access_files() = 0;
  virtual void release_filesystem() = 0;
};

然后,此类(接口)的特定实现可能对其中的某些方法无效。或者,基类可以为初始化/释放声明空方法,而不是将它们声明为虚拟方法。

最后(可耻的是),有时您维护一个非常旧的应用程序。您担心删除方法会破坏事情。当您具有无法正确理解的复杂继承或具有许多函数指针(回调)时,就会发生这种情况。您只需删除其中的代码,以便无论如何都可以调用它们而不会破坏任何内容。


0

当您可能在已完成的程序中使用空函数时,Rufflewind做得很好。以我的经验,它通常会在未完成的程序中更频繁地使用,因此您可以计划要编写的内容,并使它仍然可以编译,直到您真正实现它为止。换句话说,它通常只是一个占位符。

在python的情况下是有必要的,因为它使用缩进标记块,这与使用braces的类似C的语言不同{}。这意味着,如果没有pass,解析器将无法判断您是要保留为空白还是忘记了。包括在内pass使解析器更加简单,并在查找未实现的块时为您提供方便的单词来进行搜索。


1
对于未完成的代码,抛出NotImplementedError是一种更合适的解决方案,因为“错误永远都不能静默传递”,而在实时程序中调用未实现的函数是错误。
ivan_pozdeev 2015年

那要看。对于您提供的代码,是的。但是,如果您希望在一个小时内实现该代码,而在进行单元测试时就不执行该代码,那么不执行任何代码可能是一个更好的选择。我的工作流程通常是1)用pass 2 )编写存根方法2)编写测试返回值的单元测试3)验证测试失败(因为方法返回未定义)4)实施方法5)验证测试现在通过
机器人升格

0

虽然这不是您期望在Python中完成的事情,但是在设备驱动程序世界中,有时您需要提供一个空函数来处理您可能不会(a)知道或( b)即使在乎也不在乎。

您还会在C中通过回调看到这一点。有时,您会看到仅提供了回调的ASSUMES代码,并尝试调用它,而忽略了存在空指针的风险。在这种情况下,您所能做的就是提供一个空的回调例程。(是的,我有一个特定的供应商。)


pass在编写代码时,尤其是在类中,当我想要在一切完成之前可以运行的东西时,我经常使用占位符。实际上{},它等效于python,而python由于不使用花括号而无法执行。从这个意义上说,我所知道的所有语言都允许这样做,只是只有一对夫妇python需要关键字。即使在集会的日子里,我们也有过NOP

@StevenBurnap,通常当我做这样的事情时,我会在本地添加printf(“ >>>例行X​​XX,称为\ n”);
John R. Strohm 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.