题 Python:为什么模块中不允许`return`


如果你看一下从模块编译的Python字节码,你会在最后看到:

10 LOAD_CONST               0 (None)
13 RETURN_VALUE        

即一个 return 在模块的根级别完全有效。但是,如果您尝试在源代码中使用它,则会得到:

SyntaxError: 'return' outside function

为什么?


这当然是语言设计的决定。但为什么要这样做?一个 return 在模块中通常非常有用。例如。我有时想在模块的开头编写这段代码:

import sys
if sys.platform != "linux2":
    print "your platform is not yet supported"
    # define some stubs
    def foo(): pass
    def bar(): pass
    return

而且我不想在那里引发异常(因为这会导致模块无法加载我不想要的)。


实际上,我将一些代码组合在一起,可以动态操作Python字节码并只返回(或者在我的情况下跳转到返回完成的末尾)。这很有效。它只是CPython的唯一原因是因为没有标准的方法来操作代码对象。

这里 是代码。


对于可能的答案:我更喜欢真实的证据,Guido van Rossum的一些过去的陈述,或者仅仅是随意的讨论。我当然可以利用这两种优势(如已经提出的那样)和自己的劣势,但我并没有真正看到反对它的重要原因。


20
2017-09-07 04:37


起源


你为什么不提出例外?这将停止执行并返回有关调用者为什么要监听异常的信息 - Joran Beasley
@JoranBeasley:它不会加载模块。我说的是我仍然想要加载模块的情况。 - Albert
然后有一个单独的模块,用户可以导入...如果不支持它不应该支持...在 __init__.py 你可以做 try:import no_linux2; except:import alt_implementation as no_linux2 - Joran Beasley
如果模块的一部分是可用的而另一部分不可用,那么可以说,它们应该被分成子模块,这些子模块处理系统相关的东西并被导入到主模块的命名空间中。 (例如。 if sys.platform == 'linux2': import _linux_dependent as submod; ...)。这具有使系统相关代码保持独立的优点。 - mgilson
这不是原因,而是这个 什么时候 可以帮助别人找到答案。它首次出现在1990年的Python / compile.c中,提交消息为“编译”版本' hg.python.org/cpython/annotate/a6934380c6e7/Python/... - Adam Wagner


答案:


我猜这是蟒蛇开发者的一个决定,因为它强迫了 用户 该模块处理他们的系统不受支持的事实(而不是让模块的开发人员猜测应该发生什么)。想象一下,当他们在Windows机器上突然运行代码时,他们会感到惊讶 module.foo() 没有按预期工作。 (你的警告 print 语句可以完全埋没在可能被转储到stdout的各种其他垃圾中。

我认为最常见的处理方法是提高一个 ImportError 要么 NotImplementedError。然后 用户 可以决定他们是否可以在没有这个模块的情况下继续生活,(通过捕获例外情况),或者他们的程序是否会崩溃并在那里燃烧。


6
2017-09-07 04:43



我想不出一个人为什么要从模块中回复的正当理由...... - Joran Beasley
对于Python来说这是非常不寻常的,它通常不会强迫(相反)。 - Albert
@Joran比斯利一些 开源Python框架 我共同开发将从呼叫能力中获益 return 来自一个模块。您个人无法设想有效的用例 不 暗示没有有效的用例。 - Cecil Curry
@mgilson要求 if-elif-else 构建仅仅是为了规避语言缺陷既是可怕的又是反恐怖的。任何可观察的运气,最终的Python 4将纠正这个和其他任意的句法疏忽(例如,限制的可怕性 lambda 仅仅是表达式的功能)。 - Cecil Curry
@CecilCurry - 我认为这局限 lambda 简单的表达是一个很好的决定。我已经阅读了太多的javascript,其中一个内联函数和下一个内联函数之间的界限变得难以辨别:-)。此外,正如我在答案中所说,提出异常似乎是一个更好的决定,而不是只是默默地工作,但后来在一个不相关的点死亡,因为你期望在那里的东西没有。 - mgilson