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

Cla*_*ell 344 python null return

考虑三个功能:

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

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"
Run Code Online (Sandbox Code Playgroud)

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

小智 451

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

运用 return None

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

在下面的例子中,如果给定的是人,则返回person's' .如果它不是人类,我们会返回,因为它没有(让我们假设它不是动物或者左右).motherpersonNonepersonmother

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None
Run Code Online (Sandbox Code Playgroud)

运用 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()
Run Code Online (Sandbox Code Playgroud)

注意:您永远不应该这样做var = find_prisoner_with_knife(),因为返回值并不意味着被捕获.

使用无return可言

这也将返回None,但该值不应被使用或捕获.它只是意味着功能成功结束.它与C++或Java等语言return中的void函数基本相同.

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

def set_mother(person, mother):
    if is_human(person):
        person.mother = mother
Run Code Online (Sandbox Code Playgroud)

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

  • 如果要将var传递给其他接受None的函数,则var = get_mother()没问题-“ never”有点极端 (4认同)

Dav*_*arx 29

是的,他们都是一样的.

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

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      
Run Code Online (Sandbox Code Playgroud)

  • 小心点......`dis.dis`返回`None`: - X. (4认同)

mgi*_*son 18

它们各自返回相同的单例None- 没有功能差异.

我认为,return除非你需要提前退出函数(在这种情况下裸露return更常见),或者返回除了之外的其他内容,否则放弃声明是合理惯用的None.它也是有道理的,return None当它在一个函数中有另一个返回其他东西的函数时,它似乎是惯用的None.return None显式写出是读者的视觉提示,有另一个分支返回更有趣的东西(并且调用代码可能需要处理两种类型的返回值).

往往在Python,它返回函数None的使用类似void的功能用C -他们的目的通常是对输入参数进行操作的地方(除非你使用全局数据(战栗)).返回None通常会使参数变异更明确.这使得更清楚为什么return从"语言惯例"的角度来看这句话是有意义的.

也就是说,如果您正在使用已经围绕这些事情预先设定约定的代码库,我肯定会效仿以帮助代码库保持统一...


Fab*_*ano 11

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

区别在于文体,但请注意PEP8要求使用保持一致:

在 return 语句中保持一致。函数中的所有 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)
Run Code Online (Sandbox Code Playgroud)

不:

def foo(x):
    if x >= 0:
        return math.sqrt(x)

def bar(x):
    if x < 0:
        return
    return math.sqrt(x)
Run Code Online (Sandbox Code Playgroud)

https://www.python.org/dev/peps/pep-0008/#programming-recommendations


基本上,如果您曾None在函数中返回非值,则意味着返回值具有意义并且旨在被调用者捕获。所以当你 return 时None,它也必须是明确的,None在这种情况下传达的意思是,它是可能的返回值之一。

如果你根本不需要 return,你的函数基本上是作为一个过程而不是一个函数,所以不要包含这个return语句。

如果您正在编写一个类似过程的函数并且有机会提前返回(即您已经完成了该点并且不需要执行该函数的其余部分)您可以使用空 an returns 向读者发出信号它只是执行的提早结束,None隐式返回的值没有任何意义并且不打算被捕获(类似过程的函数总是返回None)。


Yeh*_*rtz 5

就功能而言,它们都是相同的,它们之间的区别在于代码的可读性和风格(这也很重要)