返回,返回无,根本没有返回?

时间:2013-03-08 18:12:15

标签: python null return

考虑三个功能:

def my_func1():
  print "Hello World"
  return None

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"

他们似乎都返回无。这些函数的返回值如何表现有什么不同?是否有理由更喜欢一个与另一个相比?

5 个答案:

答案 0 :(得分:413)

关于实际行为,没有区别。他们全都返回None即可。但是,所有这些都有时间和地点。 以下说明基本上是如何使用不同的方法(或者至少我应该如何使用它们),但它们不是绝对的规则,因此如果你认为有必要,你可以将它们混合起来。

使用return None

这告诉该函数确实意味着返回一个值供以后使用,在这种情况下它返回None。然后可以在其他地方使用此值None。如果函数中没有其他可能的返回值,则永远不会使用return None

在以下示例中,如果给出的person是人,则返回mother' s person。如果它不是人类,我们会返回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等语言中的return函数中的void基本相同。

在下面的示例中,我们设置了人的母亲姓名,然后在成功完成后退出该功能。

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother

注意:您永远不应该var = set_mother(my_person, my_mother),因为返回值并不意味着被捕获。

答案 1 :(得分:26)

是的,它们都是一样的。

我们可以查看解释后的机器代码,以确认他们都在做同样的事情。

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      

答案 2 :(得分:18)

他们每个都返回相同的单身None - 没有功能差异。

我认为,除非你需要提前退出函数(在这种情况下裸return更常见),否则放弃return语句是合理惯用的,或者返回一些东西None以外的人。它也是有意义的,并且当它在一个函数中写return None时,它似乎是惯用的,它有另一个路径返回None以外的东西。明确地写出return None是读者的视觉提示,有另一个分支返回更有趣的东西(并且调用代码可能需要处理两种类型的返回值)。

通常在Python中,返回None的函数与C中的void函数一样使用 - 它们的目的通常是对输入参数进行操作(除非你'使用全球数据(颤抖))。返回None通常会使参数变异更明确。这使得更清楚为什么从“语言约定”的角度省略return语句是有意义的。

那就是说,如果你在一个已经围绕这些事情预先设定约定的代码库中工作,我肯定会效仿,以帮助代码库保持统一......

答案 3 :(得分:2)

就功能而言,它们都是相同的,它们之间的区别在于代码的可读性和样式(要考虑这一点很重要)

答案 4 :(得分:0)

正如其他人回答的那样,结果完全相同,在所有情况下都返回None

差异是风格上的,但是请注意,PEP8要求用法必须一致:

  

在return语句中保持一致。或   函数应该返回一个表达式,或者都不返回。如果有的话   return语句返回一个表达式,任何return语句在没有   返回的值应将其明确声明为return None,并且   函数的末尾应包含显式return语句   (如果可以访问)。

     

是:

     
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语句。

如果您正在编写类似过程的函数,并且有机会早点返回(即,此时您已经完成了,不需要执行其余的函数),则可以使用{{1 }}向读者传达信号,这只是执行的早期完成,隐式返回的return值没有任何意义,也不意味着被捕获(类似过程的函数总是返回{{1 }})。