"передать" то же, что и "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
- нет.