Плохо ли называть неиспользуемую переменную одним подчеркиванием?

44

Часто, когда синтаксис языка требует, чтобы я назвал переменную, которая никогда не используется, я назову ее _.

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

Типичным примером того, где я делаю это, является именование подзапросов в SQL.

SELECT *
FROM
(
    SELECT *
    FROM TableA
    JOIN TableB
        ON TableA.ColumnB = TableB.ColumnB
    WHERE [ColumnA] > 10
) _ --This name is required, but never used here
ORDER BY ColumnC

Другой пример - переменная цикла, которая не используется.

array = [[] for _ in range(n)] # Defines a list of n empty lists in Python

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

Мои коллеги не согласны. Говорят, что даже иметь одно (буквенное) имя персонажа лучше, чем _.

Я ошибся? Это плохая практика?

Крис Харпер
источник
4
Я думаю, что имена переменных должны следовать теории информации, то есть длина - это логарифмическая взаимная вероятность их использования (общие переменные имеют короткие имена). Одна буква алфавита кажется неправильным путем.
dan_waterworth
2
@dan_waterworth Использование одинарных или двойных символов в качестве псевдонимов таблиц является довольно распространенной практикой в ​​сценариях SQL. Так как вам обычно приходится писать много [table].[column]идентификаторов, это помогает читабельности просто использовать [T].[column]. Это зависит от сценария, конечно. Немного подобный выбор отлично подходит, но если бы скрипт был очень большим, я мог бы использовать более описательные имена.
CodexArcanum
5
Я бы предпочел, чтобы вы использовали "пустышку". Это кричит мне, что они там, потому что язык требует переменную, у которой нет семантического контекста за пределами этих нескольких строк. _ плохо читается для человека. (одна из причин, по которой я ненавижу PERL - я не могу напечатать или прочитать это)
Крис Кадмор
1
Примечание: то, что вы называете, это производная таблица , а не подзапрос.
Ник Чаммас
2
Ключевое слово var в c # не имеет этого значения, это просто обычное объявление переменной, где выводится тип.
Франческо Де Виттори

Ответы:

60

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

Telastyn
источник
13
+1. dummyбыло бы хорошо, joined_abбыло бы лучше.
Blrfl
5
+1, есть соглашение, где я работаю, чтобы использовать '_' для неиспользуемых переменных. Я думаю, что это хорошая конвенция, но я согласен с этим ответом для случая ОП. В идеале кодовые базы должны выглядеть так, как будто они написаны одним человеком.
dan_waterworth
20
«_» - это хорошо известный стандарт Python.
Нил Г
2
Если ваша компания использует какой-либо Perl, использование $ _ может иногда вызывать удивительное поведение.
Plutor
2
В прологе подчеркивание означает, что переменная будет анонимной и поэтому не используется.
Иван
44

Я бы сказал, что это приемлемая практика. Это редкий случай, когда я считаю большинство ошибочными и нуждающимися в обновлении своих знаний о последних идеях программирования. Во многих языках, в частности в функциональных языках на основе ML, таких как Haskell и OCaml, очень часто используется _как «неиспользуемая» переменная. Даже Lua, который не предлагает явной языковой поддержки для этого, поощряет использование _в качестве заполнителя соглашением.

Некоторые языки (Haskell, Lua и DI думают о моей голове) также предлагают соглашение, согласно которому переменные, начинающиеся с подчеркивания, не генерируют предупреждения компилятора о «неиспользуемой локальной переменной», которая дает _самое короткое имя неиспользуемой переменной. Вы могли бы использовать что-то вроде, _unusedно я согласен с вами, что это просто создает беспорядок.

CodexArcanum
источник
В конкретном случае SQL, я рассмотрел его, и коллеги могут быть правильными здесь. Я очень часто использую одну заглавную букву для псевдонимов таблицы (и часто R (esults) для подвыборов). Я думаю, что использование *в select является очень плохой вещью, потому что, если таблица меняет ваш набор результатов, также неожиданно меняется. Поэтому мне обычно требуется псевдоним из одного символа для определения столбцов, которые я выбираю. Если вы прекратите использовать *, вы перестанете нуждаться в «неиспользованном» имени.
CodexArcanum
11
Строго говоря, по крайней мере в Haskell, _это шаблон, а не переменная. Это тонкое различие, но это означает, что вы можете использовать его несколько раз примерно так же (x, _, _) = ..., тогда как попытка связать одну и ту же переменную несколько раз была бы ошибкой.
хаммар
12

В Python _это определенно приемлемо. Однако он может конфликтовать с gettextпсевдонимом _().

Другие общие конвенции являются dummy, unused; один или как префикс.

Некоторые инструменты анализа кода знают об этих соглашениях и не будут выдавать неиспользуемые предупреждения о переменных:

  • PyLint для _илиdummy
  • PyDev для любой переменной, начинающейся с _, unusedилиdummy
Vartec
источник
2
Кроме того, использование _фиктивных переменных в python будет конфликтовать с _последним возвращаемым значением. Например, в интерпретаторе, если вы делаете 5*5в строке 1; тогда в строке 2 _будет указано значение 25. Однако, если вы затем установите x,_ = (3,'not used'), вы найдете, что _теперь not usedвместо последнего возвращенного значения, пока вы del _. Вы, вероятно, не должны использовать _последнее возвращаемое значение в реальном коде; но это часто удобно в интерпретаторе, когда пробует новые вещи.
Доктор Джимбоб
4
Ну, так _как последнее возвращаемое значение работает только в интерактивной оболочке.
vartec
То же самое касается Луа. Использование _ является стандартной практикой
sylvanaar
11

Это зависит от экосистемы, в которой этот код будет жить. Если _это общепринятый стандарт для обозначения «фиктивной переменной» / «неиспользуемого вывода», то во что бы то ни стало, придерживайтесь его. Если это не так, выясните, что это такое, и используйте это.

Некоторые языки программирования (например, Haskell) даже имеют этот «специальный» идентификатор, встроенный в их синтаксис, именно для тех целей, о которых вы упоминаете.

tdammers
источник
5

Осторожно, _ уже имеет внутреннее значение в некоторых языках

В Python:

9.6. Частные переменные и классовые локальные ссылки

введите здесь описание ссылки «Закрытые» переменные экземпляра, к которым нельзя получить доступ, кроме как изнутри объекта, не существуют в Python. Однако существует соглашение, которому следует большая часть кода Python: имя с префиксом подчеркивания (например, _spam) следует рассматривать как непубличную часть API (будь то функция, метод или элемент данных) , Это следует рассматривать как деталь реализации и может быть изменено без предварительного уведомления.

Еще одно упоминание в PEP 8 (Руководство по стилю для кода Python):

Описательный: Стили именования

_single_leading_underscore: слабый индикатор «внутреннего использования». Например, из M import * не импортируются объекты, имя которых начинается с подчеркивания.

В C #:

Обычно используется для обозначения закрытых переменных, которые имеют публичные / внутренние свойства. Но в эти дни практика обычно смотрит вниз .

В JavaScript:

Существует библиотека под названием underscore.js, которая использует подчеркивание в качестве префикса для нестандартных расширений прототипов.

Пример:

var object = { some:'stuff' };
var newObject = _.clone(object);

Что приводит меня к моей точке зрения. Что не так с классическими соглашениями о переменных-заполнителях.

var i, j, k, l; // iterator placeholders
var x, y, z, xx, yy, zz // value placeholders
var foo, bar, bas, fixx, buzz, qux, etc... // demonstration placeholders

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

Эван Плейс
источник
В Scala: это подстановочный знак / символ-заполнитель, но в качестве заполнителя вы можете ссылаться на него только один раз .
Рекс Керр
@RexKerr Интересно. Не стесняйтесь редактировать это в ответ, если хотите. Я бы, но я не знаком со скалой.
Эван Плейс
Комментарий должен сделать. Любой, кто использует Scala, знает об этом, а тот, кто не использует Scala, вероятно, не будет иметь совместимости с Scala в верхней части списка причин, чтобы / не делать что-то.
Рекс Керр
Я думаю, что использование одного из этих "условных" заполнителей для неиспользуемых переменных было бы плохой практикой, так как это заставило бы меня подумать, во-первых, "какого черта этот парень не назвал эту вещь лучше ?? и через некоторое время я обнаружил, что это потому, что переменная не используется.
igorsantos07
@ igorsantos07 Я полностью согласен. Я предпочел бы дать описательное имя даже для временных переменных. Цель этого ответа - продемонстрировать, почему подчеркивание не является хорошим выбором для соглашения об именах; из-за его существующего значения во многих языках.
Эван Плейс
2

Я использую "пустышку" для такого рода вещей. Или "дерьмо", если я просто что-то тестирую :) Назовите свои переменные, чтобы описать, что они из себя представляют. Если они фиктивные, неиспользуемые переменные, назовите их так.

Филипп Шмидт
источник
0

Я считаю, что это плохая практика, потому что

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

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

(Я не знаю Python: действительно ли нужна эта конструкция?)

Денис Сегюре
источник
2
Если вы используете его для фильтрации многократных возвратов, то это также будет следствием использования его для аргументов фиктивной функции. На самом деле, между ними нет особой разницы: в функциональных языках сопоставления с образцом вы можете писать let (a,b,_) = f(x,y,z)так же хорошо let f(x,y,_) = (g(x),h(x),g(y)), или как угодно. - И да, часто бывает полезно иметь фиктивные параметры: не как единственное определение функции, а для полиморфной функции или определения с альтернативными определениями, сопоставленными с образцом, это часто бывает естественным.
оставил около
1
Ваш второй пункт противоречит вашему главному пункту: в Go это по сути означает то же самое, что и «Я не использую это значение».
Кейси Кубалл
0

Это может быть синтаксически допустимым, и это может быть нормально, как часть стандарта.

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

Алан Делимон
источник
0

Я думаю, что это неправильно, потому что:

1) Труднее увидеть, так как пикселей не так много.

2) Если их больше одного _, откуда вы знаете, какой? - или что новый разработчик «следовал правилам» и оставил их использование исключительно локальным по объему?

3) Это практика, которая не помогает. Использование однобуквенных имен переменных - это старая школа (то есть мое первоначальное образование!). Я увижу их ... и затем добавлю комментарии, чтобы сказать, что делает код, и это плохая практика в современном мире. Я использую как можно больше длинных имен переменных, чтобы каждый, независимо от уровня программирования или знания кода, мог просто «прочитать» его почти как на английском. Использование однобуквенных имен является очень распространенной практикой для старого кода и для более старых программистов (опять же, включая меня), но это не делает его нормальным.

наркоман
источник
9
«откуда вы знаете, какой из них» вы не знаете : в этом-то и дело, вы не используете переменную. Так что это также не имеет значения, если _уже используется во внешней области видимости; затем он будет затенен (или что бы ни делал ваш язык в таких случаях), но в любом случае ни один из них на самом деле не используется.
оставил около
0

Чтобы избежать коллизий в пространстве имен и разрешить отладку, в случае, если имя переменной является вашей единственной подсказкой, возможно, было бы лучше назвать ее «join_ab_unused».

Вдохновленный Birfl.

Hack Saw
источник
0

Да, это плохая практика по двум причинам:

  1. Префикс неиспользованной переменной с подчеркиванием не является общепринятым стандартом. Скорее всего, будут игнорироваться «непосвященные».
  2. Я видел, как некоторые люди ставят префикс закрытых членов с подчеркиванием, и ваш стандарт очень запутает таких людей.
Джим Г.
источник
0

То, что вы пытаетесь сделать, - это написать код в более приятной версии SQL, в которой нет необходимости заставлять вас придумывать имя для чего-то бесполезного.

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

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

Kaz
источник
0

Это зависит от языка. В java да, это плохо и может быть опасной тенденцией к добавлению в ваш код, в основном потому, что инструменты, использующие отражение, не очень хорошо обрабатывают подчеркивание, так как они находятся вне соглашений по именованию переменных java. В питоне это тоже плохо, но не так плохо. В clojure все на 100% нормально, и на самом деле идиоматично использовать _ в качестве заполнителей в операторе let.

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

jayunit100
источник
5
Я не согласен, что это плохая практика в питоне. Это широко известное соглашение
Daenyth
0

Это было бы плохо в Perl, который использует $ _ (а иногда и _) в качестве специальной переменной.

В общем, я бы держался подальше от этого только потому, что _, кажется, определенно изменяемый язык. Если бы я увидел твой код, я бы в документации искал, что _ было, пока не понял, что это просто дурачок. Ничего плохого в DUMMY, $ DUMMY, что угодно.

Рич Гомолка
источник
0

Я бы избегал подчеркиваний в начале переменных, если вы не уверены, что они не склонны указывать что-либо еще на заданном языке или структуре при интенсивном использовании. Например, в Python двойное подчеркивание имеет тенденцию указывать на магическую переменную. В JQuery и других библиотеках JS одно подчеркивание имеет тенденцию указывать на запасную переменную для перезаписей пространства имен. Это также популярное соглашение об именах для включаемых файлов, которые, в свою очередь, имеют тенденцию переноситься в код, который обрабатывает включения в виде var.

Эрик Реппен
источник