在Python中,可以创建一个没有显式返回的过程。即:
def test(val):
if 0 == val:
return 8
此外,可以将该函数的结果分配给变量:
>>> a = test(7)
>>> print `a`
'None'
为什么会这样?令人困惑的设计决策背后是什么语言逻辑?为什么不简单地引发编译错误?
编辑:是的,我意识到它的运作方式。谢谢。我的问题是为什么?在您的代码中引入细微错误似乎是一种可靠的火灾方式。正如下面e-satisf所提到的那样,似乎违背了“明显更好然后隐含”的非常明智的蟒蛇格言。那么,这有什么用呢?它只是一个设计监督或简化的假设还是一个经过慎重考虑的决定?
编辑:大家都同意用这种方式表达意图要好得多:
def test(val):
if 0 == val:
return 8
else:
return None
如果是这样,为什么Python更喜欢前一种风格来引发编译时异常?
编辑:S.Lott明确地提出了这一点(其他人也这样做,他似乎对我来说最清楚)这种行为是因为Python是一种动态语言,因此无法在编译时检查时间,系统的运行时行为。
由于程序(那些不返回值的函数)和函数(那些没有返回值)之间没有区别,因此在编译时没有任何内容可以强制执行。这意味着当我们遇到运行时行为时,我们要么在某些情况下发生灾难性故障(我们抛出异常),要么我们默默地假设程序员知道他们在做什么并理解默认行为。
pythonic方式是做后者,C风格的方式是做前者。
这似乎是有道理的理由。
S.Lott明确的理由被隐藏在对已接受答案的评论中,所以我认为最好总结一下。
我会暂时接受答案,看看S.Lott是否正式回答。否则,我会给SilentGhost点。
答案 0 :(得分:26)
虽然每个函数可能没有显式返回,但它会有一个隐式函数,即None
,它偶然是一个普通的Python对象。此外,函数通常return None
明确。
我认为返回无隐式只是一种易于使用的优化。
P.S。我想知道你建议编译在以下情况下会做什么:
def t():
if True:
return 'ham'
PPS return
语句表示要返回需要,None
,42
或{{1} }。但是,有些函数并没有真正返回任何内容,例如'spam'
或list.sort
,因此在每个__init__
结尾处要求return None
语句会产生开销。
答案 1 :(得分:11)
Python从不检查人类的不当行为。语言哲学是假设程序员是成年人并且知道他们在做什么。
自:
返回无比提出错误更容易。
E.G:
function_stack = [func1,func2,func3]
for f in function_stack :
a = f()
if a is not None :
# do something
无论f是f()是函数还是程序。 Python中没有这样的东西。您可以应用所有功能,并处理输出(如果有)。
答案 2 :(得分:6)
嘿。从Java的角度来看,你的问题很明显。它应该抛出一个错误。
但是,如果你从Perl的角度来看它,它根本不是显而易见的。你将变量设置为无价值,这很重要。
一切都与打字有关。与Java一样,Python是strongly typed,但与Java不同,它也是dynamically typed。大多数动态类型语言允许这样的恶作剧。
答案 3 :(得分:3)
很漂亮......
在None
对我来说有意义的情况下,它会返回val != 0
。
Python 2.6.1 (r261:67515, Jun 18 2009, 17:24:16)
[GCC 3.3.3 (SuSE Linux)] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> def test(val):
... if 0 == val:
... return 8
...
>>> a = test(8)
>>> print a
None
>>> print test(0)
8
>>>
你有什么理由认为行为是错误的吗?
如果你需要强大的编译时类型检查,你可以使用c ++但是对于python它似乎非常灵活,我认为这是你为你的任务选择python时你想要的。
答案 4 :(得分:1)
什么编译器?字节码编译器在导入时检查代码的语法,但语法不包括“检查返回的所有路径”。所以当test()在运行时被调用,并且x的值不是0而我们刚刚退出函数时,应该我们做什么?返回0?为什么不-1,或“”,或-infinity?因此,在没有显式返回语句的情况下,应始终返回一个不错的中性值 - 该值为None。这是该语言的标准功能 - 欢迎使用Python!
答案 5 :(得分:1)
这是因为dynamic typing。
你不必区分turbo pascal的程序和功能。它们都是函数,它们默认返回None
,这在逻辑上是正确的。如果您没有说什么,则不返回任何内容,None
。
我希望现在更有意义 -