"передать" то же, что и "return None" в Python?

Я изучаю python примерно через неделю, вот вопрос:

код

def Foo():
    pass

def Bar():
    return None

Использование

a = Foo()
print(a)
# None
b = Bar()
print(b)
# None

Вопрос: 1. Почему нам нужно пройти, когда у нас уже есть возвращение? Нет? Есть ли какой-то сценарий, который возвращает None, не может обрабатывать, но может пройти?

Ответ 1

В таких языках, как Python, у вас есть два типа "вещей", которые оцениваются: выражения и утверждения. Выражения - это выражения, которые оцениваются. Например, 1, 1+1 или f(x) - все выражения, оценивающие что-то.

Для сравнения, утверждения не "возвращают" что-либо, а вместо этого "действуют на окружающую среду". Например, x=3 устанавливает переменную x в значение 3. def f(x): return x + 1 задает значение f для функции. Это не "оценивает" что-либо, что изменяет текущую среду, в которой оцениваются вещи.

Имея это в виду, вам иногда нужен пустой оператор. По синтаксическим причинам в Python есть места, где вам нужно утверждение, но если вы не хотите, чтобы что-то здесь происходило, вам может потребоваться выразить, что происходит именно "ничего". Один из способов - оценить выражение и ничего не делать с ним:

def f():
    1

Но случайный взгляд на это может означать, что эта функция возвращает 1: вместо этого вы можете использовать pass, как явно заявляя: "ничего не делать":

def f():
    pass

Теперь есть еще один улов: я упоминал ранее, что f(x) является выражением. Но в двух приведенных выше примерах я не помещал никаких return, так что эти оценки? Ответ: вызов функции возвращает (т.е. Оценивает) None, если не указано иное. Итак:

def f():
    pass

def g(x):
    if x > 2:
        return x

def h():
    return None

f() # None
g(3) # 3 -> we explicitely say `return x`
g(1) # None -> no return specified for that path
h() # None -> we explicitely say `return None`

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

Ответ 2

pass - это "пустая" команда, но return останавливает функцию/метод.

Примеры:

def func():
    do_something()      #executed
    pass
    do_something_else() #also executed

а

def func2():
    do_something()      #executed
    return None
    do_something_else() #NOT executed

Во втором случае return None: "остановить функцию и вернуть None". Но pass - это как "перейти к следующей строке"

Ответ 3

Примеры, которые должны отвечать на оба вопроса:

Пасс может использоваться в обработке исключений:

try:
    something()
except:
    pass  # does not return
this_still_executes()

Пасс может использоваться для объявления классов без каких-либо новых элементов:

class CustomError(Exception):
    pass

Ответ 4

Все функции/методы/вызовы в Python return None в конце, если вы вручную не вернете какое-либо другое значение, конечно. Вы можете себе представить, что каждая функция имеет неявный оператор return None после всего вашего пользовательского кода. Если вы выйдете из функции раньше, используя свой собственный оператор return, он просто не достигнут и не имеет никакого эффекта. Также голый return без значения автоматически возвращает None по умолчанию.


В этом языке необходим оператор pass ( "ничего не делать" ), потому что мы определяем блоки кода с использованием разных уровней отступов, а не с помощью скобок (например, { ... } в C, Java и т.д.) или ключевых слов (например, if ... fi в Bash).

Итак, если вам нужен пустой блок кода где-нибудь (функция, которая еще ничего не делает, пустой класс, пустая утилита исключения,...), на других языках вы просто ничего не ставите между открывающей и закрывающей скобкой или ключевым словом. В Python вам нужен отступы, но это синтаксическая ошибка. Поэтому мы имеем pass - ничего не делать, хотя мы должны писать код в этом месте.

Некоторые примеры:

  • class MyPersonalException(Exception):
        # simple exception without any additional information or functionality
        # 'return None' would not work.
        pass
    
  • def lazy_function():
        # too lazy to do anything...
        # often used if a method needs to be implemented to match an interface,
        # but should not do anything.
        # 'return None' would work here as well.
    
  • try:
         # [do something here]
    catch:
         # we don't have to do anything if it fails, just catch and suppress the exception
         pass
    

Итак, pass просто означает ничего не делать и просто продолжать обработку следующей строки.


Резюме:

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

pass не имеет смыслового значения, он никак не интерпретируется. Его единственная цель - разрешить создание пустых блоков кода, которые в Python не были бы возможны иначе, поскольку мы не используем скобки и т.д. Для блоков окружения. Он может быть написан где угодно и всегда делает то же самое: ничего.

Ответ 5

Другой сценарий заключается в том, что pass означает что-то еще не реализовано, но будет реализовано в будущем. Например, перед написанием фактической логики вы определяете некоторые API:

def get():
    pass

def post():
    pass

def put():
    pass

...

Это семантическое значение не может быть заменено на return None. И, как сказал вираптор, иногда вы получите синтаксическую ошибку, если используете return None, а не pass.

Ответ 6

>>> import dis
>>> dis.dis(Foo)
  2           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE        

>>> dis.dis(Bar)
  2           0 LOAD_CONST               0 (None)
              3 RETURN_VALUE        

Как вы можете видеть, это те же функции точно. Нет причин использовать один над другим (в этом конкретном примере), кроме стиля, и, возможно, для того, чтобы сообщать другим кодонам, что является намерением для этой функции.

Вообще-то есть разница. Оператор return прерывает выполнение текущей функции, а pass - нет.