Существует ли какой-либо рекомендуемый / общепринятый стиль кодирования для обработки ситуаций, когда функция возвращает кортеж значений, но впоследствии используется только одно из этих значений (обратите внимание, что это в основном предназначено для библиотечных функций, которые я не могу изменить - написание обертки вокруг вызов, вероятно, немного излишним ...)? Вместо того чтобы делать
a, b, c = foo()
и затем просто не используя b
и c
какой из следующих вариантов должен быть предпочтительным (или есть другой?):
Вариант 1 (подчеркивание)
a, _, _ = foo()
(что очень ясно и просто, но может противоречить _ = gettext.gettext
используемому во многих приложениях, использующих перевод)
Вариант 2 (фиктивное имя)
a, unused, unused = foo()
(я думаю, это не очень привлекательно для других имен dummy
)
Вариант 3 (индекс)
a = foo()[0]
(для меня ()[0]
внешность не питонна ...)
python
coding-style
user49643
источник
источник
a, b = foo()[0:2]
будет ли работать? Если да: да, это так :)a, *_ = foo()
отбросит все значения, кроме первого.Ответы:
Использование подчеркивания для неиспользуемых переменных определенно допустимо. Однако следует помнить, что в некоторых кодовых базах это не вариант, так как этот идентификатор зарезервирован для сокращения
gettext
. Это наиболее частое возражение против этого стиля (хотя, насколько я могу судить, это не проблема для большинства). Я все еще рекомендую это, и всегда использую это непосредственно.Имена нравятся
dummy
илиunused
имеют тенденцию раздражать меня лично, и я не вижу их очень часто (в Python, то есть - я знаю кодовую базу Delphi, котораяdummy
свободно используется , и она также просочилась в сценарии, связанные с рассматриваемой программой). Я бы посоветовал вам против этого.Простое извлечение одного элемента из возвращенного кортежа тоже хорошо. Это также избавляет от некоторых хлопот с правильным определением количества неиспользуемых значений. Обратите внимание, что у него есть два потенциальных недостатка:
источник
Пилинт привел меня в привычку делать это так:
То есть неиспользуемые результаты имеют описательное имя с префиксом _. Pylint рассматривает локальных пользователей с префиксом _ как неиспользуемые, а глобальные или атрибуты с префиксом _ как приватные.
источник
Если во всем проекте вы делаете это только один раз или очень редко для конкретной функции, я бы использовал вариант 1, если вы знаете,
gettext
что в этом модуле нет проблем, а в противном случае вариант 3.С другой стороны, если вы делали это много - и особенно если каждый раз, когда вам нужно другое подмножество возвращаемых значений (создание обертки, чтобы просто возвращать те, которые вас интересуют, нежизнеспособны), может быть полезно написать обертку который помещает результаты в именованный кортеж или экземпляр какого-либо другого описательного класса, что позволит вам сделать:
А потом работать с
bar.a
,bar.b
иbar.c
.источник
Как уже говорили другие, подчеркивание (
_
) является стандартом. Но если для перевода используется подчеркивание, я думаю, что двойное подчеркивание - лучшая альтернатива.var, __, value = "VAR=value".partition('=')
Лучше, чем они:
var, unused, value = "VAR=value".partition('=')
var, unused_del, value = "VAR=value".partition('=')
var, _del, value = "VAR=value".partition('=')
источник
Я не программист на Python, но для меня третий вариант имеет смысл.
В варианте 3 вам абсолютно ясно, с какими ценностями вы заинтересованы иметь дело. В вариантах 1 и 2 вы присваиваете значения переменным, и, таким образом, они могут использоваться. Возможно, вы назвали их неясно, но плохое именование не является решением какой-либо проблемы.
Помимо ясности, почему вы хотите назначить неиспользуемые значения слоту в памяти (как в вариантах 1 и 2)? Это было бы плохим решением с точки зрения управления памятью.
источник
Вот общее правило: если используется только 1 из возвращенных значений, почему бы просто не вернуть это 1 значение? В случае, если флаг вызывается из нескольких мест, оставьте флаг для того же самого и верните значения в соответствии с флагом.
РЕДАКТИРОВАТЬ:
Если бы вы оказались в вашей ситуации и не написали функцию, я бы, возможно, выбрал вариант 2. Я бы оставил там фиктивные имена, чтобы параметры могли использоваться в случае необходимости. Нарезка списка будет иметь немного накладных расходов. Возможно, вы можете сэкономить несколько байтов, чтобы получить нежелательные данные.
источник
%timeit a, _, _ = foo()
против,%timeit a = foo()[0]
который привел к 123 нс против 109 нс, то есть нарезка, кажется, на самом деле быстрее, чем распаковка значения. Или вы имели в виду какую-то конкретную ситуацию?