返回、返回None和不返回?
考虑这三个函数:
def my_func1():
print "Hello World"
return None
def my_func2():
print "Hello World"
return
def my_func3():
print "Hello World"
它们看起来都返回了None
。那么,这些函数返回的值在行为上有什么不同吗?有没有什么理由让我们更喜欢其中一个而不是另一个呢?
5 个回答
其他人已经回答过了,结果是完全一样的,所有情况下都会返回 None
。
区别在于写法风格,但请注意,PEP8 要求使用时要保持一致:
在返回语句中要保持一致。一个函数里的所有返回语句要么都返回一个值,要么都不返回。如果有任何返回语句返回了一个值,那么那些没有返回值的返回语句应该明确写成
return None
,而且在函数的最后(如果可以到达)应该有一个明确的返回语句。是的:
def foo(x): if x >= 0: return math.sqrt(x) else: return None def bar(x): if x < 0: return None return math.sqrt(x)
不是:
def foo(x): if x >= 0: return math.sqrt(x) def bar(x): if x < 0: return return math.sqrt(x)
https://www.python.org/dev/peps/pep-0008/#programming-recommendations
基本上,如果你在一个函数中返回了非 None
的值,这就意味着这个返回值是有意义的,调用者应该去接收它。所以当你返回 None
时,也必须明确表示,这样才能传达出 None
在这种情况下是有意义的,它是可能的返回值之一。
如果你根本不需要返回值,那么你的函数基本上就像一个过程,而不是一个函数,所以就不要写 return
语句。
如果你在写一个类似过程的函数,并且有机会提前返回(也就是说,你在那个点已经完成了,不需要执行剩下的代码),你可以使用空的 return
来告诉读者这是一个提前结束的执行,返回的 None
值没有任何意义,也不需要被接收(这种类似过程的函数反正总是返回 None
)。
是的,它们都是一样的。
我们可以查看解释后的机器代码,来确认它们实际上在做完全相同的事情。
import dis
def f1():
print "Hello World"
return None
def f2():
print "Hello World"
return
def f3():
print "Hello World"
dis.dis(f1)
4 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f2)
9 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
10 5 LOAD_CONST 0 (None)
8 RETURN_VALUE
dis.dis(f3)
14 0 LOAD_CONST 1 ('Hello World')
3 PRINT_ITEM
4 PRINT_NEWLINE
5 LOAD_CONST 0 (None)
8 RETURN_VALUE
实际上,这些方法的行为没有区别。它们都返回 None
,就是这样。不过,在不同的情况下,这些方法各有其用。下面的说明基本上是关于这些不同方法应该如何使用(或者说我被教导的用法),但这并不是绝对的规则,如果你觉得有必要,可以混合使用。
使用 return None
这个用法表示这个函数确实是要返回一个值供后续使用,而在这种情况下,它返回的是 None
。这个 None
的值可以在其他地方使用。如果函数没有其他可能的返回值,就不应该使用 return None
。
在下面的例子中,如果给定的 person
是人类,我们就返回这个 person
的 mother
。如果不是人类,我们就返回 None
,因为这个 person
没有 mother
(假设它不是动物之类的)。
def get_mother(person):
if is_human(person):
return person.mother
else:
return None
使用 return
这个用法和循环中的 break
类似。返回的值并不重要,你只是想退出整个函数。在某些情况下,这个用法非常有用,尽管你并不常用到。
假设我们有15个 prisoners
,我们知道其中一个有刀。我们一个一个检查每个 prisoner
是否有刀。如果我们找到了那个有刀的人,我们就可以直接退出函数,因为我们知道只有一把刀,没有必要再检查其他 prisoners
。如果没有找到有刀的 prisoner
,我们就发出警报。这可以用很多不同的方法实现,使用 return
可能并不是最好的方法,但这只是一个例子,展示了如何使用 return
来退出函数。
def find_prisoner_with_knife(prisoners):
for prisoner in prisoners:
if "knife" in prisoner.items:
prisoner.move_to_inquisition()
return # no need to check rest of the prisoners nor raise an alert
raise_alert()
注意:你不应该写 var = find_prisoner_with_knife()
,因为返回值并不是要被捕获的。
完全不使用 return
这样也会返回 None
,但这个值并不是要被使用或捕获的。它只是表示函数成功结束。基本上,这和 C++ 或 Java 等语言中的 void
函数里的 return
是一样的。
在下面的例子中,我们设置了这个人的母亲的名字,然后函数在成功完成后退出。
def set_mother(person, mother):
if is_human(person):
person.mother = mother
注意:你不应该写 var = set_mother(my_person, my_mother)
,因为返回值并不是要被捕获的。