Программирование

Разница между return, return None и отсутствием return в Python

Понимание различий между операторами return в Python: явный return None, пустой return и отсутствие return. Когда что использовать для чистого кода.

5 ответов 1 просмотр

В чем разница между return, return None и отсутствием return в Python?

Рассмотрим следующие три функции:

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

def my_func2():
 print("Hello World")
 return

def my_func3():
 print("Hello World")

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

Операторы return, return None и отсутствие return в Python функционально идентичны - все они возвращают None. Различия заключаются в стилистике кода, явности намерений и соответствии рекомендациям PEP 8. Выбор между этими подходами зависит от контекста использования и желаемой читаемости кода.


Содержание


Основные различия между return, return None и отсутствием return

Все три функции, которые вы привели, действительно возвращают None. Функционально они абсолютно идентичны:

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

def my_func2():
 print("Hello World")
 return

def my_func3():
 print("Hello World")

При вызове my_func1(), my_func2() или my_func3() каждая из них выведет “Hello World” в консоль и вернет None. Но здесь кроются различия, которые выходят за рамки простого функционального поведения.

The Python return Statement: Usage and Best Practices

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

Пустой return без значения — это способ досрочно выйти из функции. Он часто используется в циклах или условиях, где нужно прервать выполнение раньше, чем дойдет до конца функции. Как отмечает один из экспертов на Stack Overflow, это своего рода “Python-way” аналог оператора break.

А вот отсутствие return вообще делает код более чистым для функций, которые не предназначены для возврата значений. Такие функции часто называют “процедурами” — они выполняют некоторые действия, но не возвращают результат.


Практическое применение оператора return в Python

Давайте рассмотрим практические примеры использования каждого подхода. Это поможет понять, когда какой вариант предпочтительнее.

Случай 1: Функция с возможностью возврата разных типов данных

python
def find_element(lst, target):
 for i, element in enumerate(lst):
 if element == target:
 return i # Нашли элемент, возвращаем его индекс
 return None # Не нашли, явно возвращаем None

В этом примере return None делает код более читаемым — мы явно указываем, что функция предназначена для возврата индекса (целого числа), но если элемент не найден, она возвращает None.

Случай 2: Функция с досрочным выходом

python
def validate_user(username, password):
 if not username:
 return # Нет имени пользователя, выходим
 
 if not password:
 return # Нет пароля, выходим
 
 # Остальная логика проверки
 if check_credentials(username, password):
 return True
 return False

Здесь пустые return используются для досрочного выхода из функции в случае ошибок. Это делает код более читаемым, чем вложенные условные конструкции.

Случай 3: Процедура без возврата значения

python
def log_message(message):
 timestamp = datetime.now().strftime("%Y-%m-%d %H:%M:%S")
 formatted_message = f"[{timestamp}] {message}"
 print(formatted_message)
 # Нет return - функция просто выполняет действие

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

Диаграмма возвратных значений в Python

Соответствие PEP 8 и стандарты кодирования

Руководство по стилю кодирования Python (PEP 8) дает рекомендации по использованию оператора return. Согласно PEP 8, следует быть последовательным в использовании операторов return:

“Either all return statements in a function should return an expression, or none of them should.”

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

С точки зрения PEP 8:

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

Однако есть нюансы. Как отмечает Julian Hysi в своем блоге, выбор стиля часто зависит от личных предпочтений и опыта программирования. Например, разработчики с Java-фоном могут чаще использовать пустой return для досрочного выхода.


Когда использовать return None, а когда просто return или отсутствие return

Решение о том, какой вариант использовать, зависит от контекста и целей вашего кода. Давайте разберем конкретные рекомендации.

Используйте return None когда:

  1. Функция предназначена для возврата значений, но в некоторых случаях возвращает None. Это делает код более явным и понятным.
python
def find_user_by_email(email):
 if not is_valid_email(email):
 return None # Явно указываем, что валидация не прошла
 
 user = db.query("SELECT * FROM users WHERE email = ?", email)
 return user # Возвращаем объект пользователя или None
  1. В функции есть несколько точек возврата, и None является допустимым значением. Явный return None помогает избежать путаницы.
python
def process_data(data):
 if not data:
 return None # Данные пустые
 
 if not isinstance(data, dict):
 return None # Неправильный тип данных
 
 # Обработка данных
 return processed_data
  1. Вы хотите подчеркнуть, что None является осмысленным возвращаемым значением, а не просто отсутствием значения.

Используйте пустой return когда:

  1. Функция не предназначена для возврата значений, но нужно выйти досрочно.
python
def save_file(content, filename):
 if not content:
 return # Содержимое пустое, нечего сохранять
 
 if not filename:
 return # Имя файла не указано
 
 with open(filename, 'w') as f:
 f.write(content)
 # Функция не возвращает ничего, просто выполняет действие
  1. Вы хотите избежать вложенных условных конструкций и сделать код более плоским.
python
def process_request(request):
 if not request.is_valid():
 return
 
 if not request.has_permission():
 return
 
 # Основная логика обработки
 process_data(request.data)

Используйте отсутствие return когда:

  1. Функция является процедурой и не предназначена для возврата значений. Это самый чистый вариант для таких случаев.
python
def log_error(error_message):
 timestamp = datetime.now().isoformat()
 with open('error.log', 'a') as f:
 f.write(f"{timestamp} - ERROR: {error_message}\n")
 # Функция просто выполняет действие, не возвращая ничего
  1. Функция всегда доходит до конца своего выполнения без досрочных выходов.

  2. Вы хотите сделать код максимально лаконичным для простых процедур.

Диаграмма возврата None Диаграмма отсутствия return

Байт-код и производительность: есть ли разница?

С точки зрения производительности и сгенерированного байт-кода все три варианта (return, return None, отсутствие return) являются эквивалентными в Python. Давайте разберемся почему.

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

Вот как выглядит байт-код для всех трех функций:

python
import dis

# Функция с return None
def func1():
 print("Hello")
 return None

# Функция с пустым return
def func2():
 print("Hello")
 return

# Функция без return
def func3():
 print("Hello")

print("Байт-код func1:")
dis.dis(func1)

print("\nБайт-код func2:")
dis.dis(func2)

print("\nБайт-код func3:")
dis.dis(func3)

Результат выполнения будет показывать, что все три функции генерируют практически идентичный байт-код. Это потому, что Python автоматически преобразует отсутствие return в return None во время компиляции.

Таким образом, с точки зрения производительности, выбирайте стиль, который делает ваш код наиболее читаемым и понятным. Различий в скорости выполнения не будет.


Лучшие практики использования оператора return

Основываясь на анализе нескольких авторитетных источников, вот лучшие практики использования оператора return в Python:

1. Будьте последовательны

Как рекомендует Real Python, будьте последовательны в использовании стиля возврата значений в пределах одной функции. Если ваша функция предназначена для возврата значений, все return должны возвращать выражения.

python
# Хорошо
def calculate_total(items):
 if not items:
 return 0
 
 total = sum(item.price for item in items)
 return total

# Плохо (несогласованность)
def calculate_total(items):
 if not items:
 return # Возвращает None
 
 total = sum(item.price for item in items)
 return total # Возвращает число

2. Используйте явный return None для улучшения читаемости

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

python
# Хорошо
def find_user(username):
 if not username:
 return None
 
 user = db.query("SELECT * FROM users WHERE username = ?", username)
 return user

# Плохо (менее понятно)
def find_user(username):
 if not username:
 return # Неясно, что возвращается
 
 user = db.query("SELECT * FROM users WHERE username = ?", username)
 return user

3. Избегайте пустого return в середине функции

Пустой return в середине функции может сделать код менее читаемым. Если возможно, переорганизуйте логику, чтобы избежать этого.

python
# Плохо
def process_data(data):
 if not data:
 return
 
 if not data.is_valid():
 return
 
 # Обработка данных
 return processed_data

# Хорошо
def process_data(data):
 if not data or not data.is_valid():
 return None
 
 # Обработка данных
 return processed_data

4. Используйте Docstrings для документирования поведения

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

python
def validate_email(email):
 """
 Проверяет, является ли строка валидным email адресом.
 
 Args:
 email (str): Строка для проверки
 
 Returns:
 bool: True, если email валиден, иначе False
 """
 if not email or '@' not in email:
 return False
 
 # Дополнительная валидация
 return True

5. Рассмотрите возможность использования исключений вместо return None

В некоторых случаях вместо возврата None может быть более уместно использовать исключения. Это делает код более явным в обработке ошибок.

python
# Вместо этого
def get_user(user_id):
 user = db.query("SELECT * FROM users WHERE id = ?", user_id)
 return user # Может вернуть None

# Лучше (используем исключение)
def get_user(user_id):
 user = db.query("SELECT * FROM users WHERE id = ?", user_id)
 if not user:
 raise UserNotFoundError(f"Пользователь с ID {user_id} не найден")
 return user

Источники

  1. Real Python — Подробное руководство по использованию оператора return в Python: https://realpython.com/python-return-statement/
  2. Stack Overflow — Ответы экспертов на вопрос о различиях между return, return None и отсутствием return: https://stackoverflow.com/questions/15300550/python-return-return-none-and-no-return-at-all-is-there-any-difference
  3. Julian’s Blog — Личный опыт использования разных стилей возврата значений: https://julianhysi.com/post/4
  4. Finxter Blog — Объяснение концепции возврата None в Python: https://blog.finxter.com/python-return-nothing-null-none-nan-from-function/

Заключение

Различия между return, return None и отсутствием return в Python в первую очередь касаются стиля кода и читаемости, а не функциональности. Все три подхода возвращают None, но они служат разным целям в разработке.

Краткое руководство по выбору:

  • Используйте return None, когда функция предназначена для возврата значений, но в некоторых случаях возвращает None
  • Используйте пустой return для досрочного выхода из функции, которая не предназначена для возврата значений
  • Используйте отсутствие return для процедур, которые просто выполняют действия без возврата результата

Выбирайте стиль, который делает ваш код наиболее понятным и соответствует стандартам вашего проекта. Помните, что PEP 8 рекомендует быть последовательным в использовании операторов return в пределах одной функции.

Leodanis Pozo Ramos / Python-разработчик

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

U

Функционально все три подхода идентичны — они все возвращают None. Разница заключается в стилистических предпочтениях и читаемости кода. PEP 8 рекомендует быть последовательным в использовании операторов return: либо все операторы return должны возвращать выражение, либо ни один из них. return None подходит, когда функция предназначена для возврата значений, но None является допустимым возвращаемым значением. Пустой return полезен для досрочного выхода из функции, а отсутствие оператора return — для функций, которым не нужно ничего возвращать. Байт-код, генерируемый Python для всех трех подходов, идентичен.

J

Я выбираю вариант с return None, когда функция действительно предназначена для возврата значения, но не может это сделать на определенной условной ветке. Я буду использовать оператор return вообще, когда функция просто не предназначена для возврата значения. Я буду использовать пустой return, когда функция не предназначена для возврата значения, и я хочу выйти из функции раньше. По сути, используя его как оператор break. Хотя я делаю это не часто, и это, вероятно, остаток моих Java дней.

Chris / Computer Science Researcher, Python Educator

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

Авторы
Leodanis Pozo Ramos / Python-разработчик
Python-разработчик
U
Разработчик
D
Data Scientist
F
Разработчик
M
Разработчик
Y
Разработчик программного обеспечения
J
Software Engineer
Chris / Computer Science Researcher, Python Educator
Computer Science Researcher, Python Educator
Источники
Real Python / Образовательный портал
Образовательный портал
Stack Overflow / Платформа вопросов и ответов
Платформа вопросов и ответов
Finxter / Образовательный портал
Образовательный портал
Проверено модерацией
Модерация
Разница между return, return None и отсутствием return в Python