Python-return, return None и нет возврата вообще

рассмотрим три функции:

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

def my_func2():
  print "Hello World"
  return

def my_func3():
  print "Hello World"

все они, похоже, не возвращают None. Существуют ли какие-либо различия между тем, как ведет себя возвращаемое значение этих функций? Есть ли причины предпочесть одно другому?

3 ответов


на фактическом поведении нет никакой разницы. Они все возвращаются!--3--> и это все. Однако для всего этого есть время и место. Следующие инструкции в основном касаются того, как следует использовать различные методы (или, по крайней мере, как меня учили их использовать), но они не являются абсолютными правилами, поэтому вы можете смешивать их, если чувствуете необходимость.

используя return None

это говорит о том, что функция действительно предназначена для возврата значения позже используйте, и в этом случае он возвращает None. Это значение можно использовать в другом месте. return None никогда не используется, если нет других возможных возвращаемых значений из функции.

в следующем примере мы возвращаем person ' s mother если person данного человека. Если это не человек, мы возвращаемся!--3--> С person нет mother (предположим, что это не животное или около того).

def get_mother(person):
    if is_human(person):
        return person.mother
    else:
        return None

Примечание: Вы никогда не должны делать var = get_mother(), так как допустим var-это словарь, и вы выполняете итерацию по var.items () это даст ошибку, цитируя None не имеет никаких элементов метода (). Если вы намеренно не возвращаете None, то об этом необходимо позаботиться в вызывающей функции соответствующим образом.

используя return

это используется по той же причине, что и break в петли. Возвращаемое значение не имеет значения, и вы хотите только выйти из всей функции. Это очень полезно в некоторых местах, даже если вам это не нужно так часто.

мы есть 15 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(), так как возвращаемое значение не предназначено для перехвата.

использование no return на всех

это также вернется None, но это значение не предназначено для использования или перехвата. Это просто означает, что функция завершилась успешно. Это в основном то же самое как return на void функции в таких языках, как C++ или Java.

в следующем примере мы ставим человека имя матери, а затем функция завершается после успешного завершения.

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

Примечание: Вы никогда не должны делать var = set_mother(my_person, my_mother), так как возвращаемое значение не предназначено для перехвата.


Да, все они одинаковы.

мы можем просмотреть интерпретированный машинный код, чтобы подтвердить, что все они делают то же самое.

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 оператор, Если вам не нужно, чтобы он вырвался из функции рано (в этом случае голый return больше всего), или вернуть что-то другое, чем None. Это также имеет смысл и, кажется, идиоматично писать return None когда он находится в функции, которая имеет другой путь, который возвращает что-то другое, чем None. Пишу return None out явно является визуальным сигналом для читателя, что есть еще одна ветвь, которая возвращает что-то более интересное (и этот вызывающий код, вероятно, должен будет обрабатывать оба типа возвращаемых значений).

часто в Python, функции, которые возвращают None используются как void функции в C -- их цель, как правило, работать с входными аргументами на месте (если вы не используете глобальные данные (страшно)). Возвращение None обычно делает более явным, что аргументы были мутированы. Это делает его немного более понятным, почему имеет смысл оставить return утверждение с точки зрения" языковых соглашений".

тем не менее, если вы работаете в базе кода, которая уже имеет предварительно установленные соглашения вокруг этих вещей, я определенно последую примеру, чтобы помочь базе кода оставаться однородной...