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

97

Я все еще привыкаю к ​​соглашениям Python и использую его, pylintчтобы сделать свой код более питоническим, но меня озадачивает тот факт, что pylint не любит односимвольные имена переменных. У меня есть несколько таких петель:

for x in x_values:
   my_list.append(x)

и когда я бегу pylint, я получаю Invalid name "x" for type variable (should match [a-z_][a-z0-9_]{2,30}- это говорит о том, что допустимое имя переменной должно быть длиной от 3 до 31 символа, но я просмотрел соглашения об именах PEP8 и не вижу ничего явного относительно одиночных строчных букв , и я действительно вижу много примеров, в которых они используются.

Что-то мне не хватает в PEP8, или это уникальный стандарт для pylint?

Аманда
источник

Ответы:

47

PyLint проверяет не только рекомендации PEP8. У него также есть свои собственные рекомендации, одна из которых заключается в том, что имя переменной должно быть описательным и не слишком коротким.

Вы можете использовать это, чтобы избежать таких коротких имен:

my_list.extend(x_values)

Или настройте конфигурацию PyLint, чтобы указать PyLint, какие имена переменных подходят.

Варвариук
источник
10
Использование _для хранения временных значений является антипаттерном. Переменные подчеркивания указывают на нерелевантные / отброшенные значения, а не на временное присвоение, например iили x. Кроме того, в интерпретаторе есть особое значение для хранения последнего значения последнего выражения.
Джеймс
123

Немного подробнее о том, что заметил Алекс Герни: вы можете указать PyLint, чтобы он делал исключения для имен переменных, которые (вы ругаетесь) совершенно ясны, даже если меньше трех символов. Найдите или добавьте в свой файл pylintrc под [FORMAT]заголовком:

# Good variable names which should always be accepted, separated by a comma
good-names=i,j,k,ex,Run,_,pk,x,y

Здесь pk (для первичного ключа), x и y - добавленные мной имена переменных.

млн.
источник
7
Это лучший ответ.
giorgiosironi
1
Кажется, не работает pylint 1.8.3. pylint.pycqa.org/en/1.8/user_guide/options.html
Джеймс,
2
Я бы очень хотел, чтобы pylint принимал (по запросу) короткие вары, когда они используются в понимания. Сравните return [customer_address for customer_address in thing.get_customer_addresses() if customer_address.is_proper()] против return [a for a in thing.get_customer_addresses() if a.is_proper()] Я утверждаю, что последнее более понятно, поскольку это очевидно из контекста. В общем, переменная длина должна соответствовать области действия переменной.
EdvardM
22

В строго типизированных языках переменные имени из одной буквы могут быть нормальными, потому что вы обычно получаете тип рядом с именем в объявлении переменной или в прототипе функции / метода:

bool check_modality(string a, Mode b, OptionList c) {
    ModalityChecker v = build_checker(a, b);
    return v.check_option(c);
}

В Python вы не получите эту информацию, поэтому, если вы напишете:

def check_modality(a, b, c):
    v = build_checker(a, b)
    return v.check_option(c)

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

def check_modality(name, mode, option_list):
    checker = build_checker(name, mode)
    return checker.check_option(option_list)

и вы даже добавляете строку документации, объясняющую, что делает этот материал и какие типы ожидаются.

Герни Алекс
источник
7
Вместо «компилируемых языков» я бы написал «явно типизированные». Например, Haskell тоже компилируется, но вы можете писать неявные объявления, как в Python.
Себастьян Мах
14
Хотя я согласен с вами в этих случаях, использование 3 или более символов в имени переменной не означает, что оно будет описательным. Я сейчас использую, with open(FILE) as f: items = f.readlines()например, где переменная fдействительно очевидна, но получаю предупреждения pylint. Это заставило меня перейти на flake8.
Axel Örn Sigursson
3
вы также можете изменить правила pylint, чтобы разрешить 'f' имя переменной. Уже есть исключения для i, j AFAIR.
gurney alex
10
для людей, которые проголосовали против этого ответа: я тот парень, который ввел правило в Pylint, и причина точно указана. Вы можете не согласиться с этим решением, но это, тем не менее, ответ на вопрос ...
gurney alex
1
Я полностью следую вашим рассуждениям, однако часто в алгоритмах и математическом программировании некоторые значения обычно называются одной буквой. Я думаю, что вызываемая функция fполностью отличается от OptionListвызываемой c. Особенно когда я не могу его переименовать, functionпотому что он затеняет встроенный.
кап
19

В настоящее время также есть возможность переопределить регулярное выражение. Т.е. если вы хотите разрешить одиночные символы в качестве переменных:

pylint --variable-rgx="[a-z0-9_]{1,30}$" <filename>

Таким образом, pylintбудет соответствовать PEP8 и не принесет дополнительных нарушений. Также вы можете добавить его в .pylintrc.

Джимилиан
источник
3
Для версии > 1.8.3это похоже на ответ. Может это в вашем , .pylintrcа также для постоянной конфигурации: variable-rgx=[a-z0-9_]{1,30}$.
Джеймс
7
--variable-rgx = "[a-z _] [a-z0-9 _] {0,30} $" может быть немного более подходящим, «9» не должно быть допустимым именем переменной.
Эрик Ле Форт,
16

Глубинная причина в том , что вы , возможно , помните , что вы хотели a, b, c, x, y, и zиметь в виду , когда вы писали код, но когда другие читают его, или даже когда вы вернетесь в свой код, код становится гораздо более удобным для чтения , когда вы даете это семантическое имя. Мы не пишем что-то один раз на доске, а потом стираем. Мы пишем код, который может просуществовать десять или более лет и быть прочитанным много-много раз.

Используйте семантические имена. Семантические имена , которые я использовал, были , как ratio, denominator, obj_generator, pathи т.д. Это может занять дополнительное второе или два типа их, но время вы сэкономить , пытаясь выяснить , что вы написали , даже полчаса с тех пор так и стоит .

Аарон Холл
источник
7
Спасибо. Вот последний код - gist.github.com/amandabee/8969833 - я понимаю вашу точку зрения о коде, который я (или вы) могу прочитать через год, но в этом случае я думаю, что x и y действительно описательны.
Аманда
OTOH, если я извлекаю элемент <dt /> из XML-документа, сохранение его в переменной 'dt' кажется довольно ясным, в то время как сохранение его как 'date' (которое представляет собой этот элемент) может сбивать с толку, и придумывать что-то вроде «the_dt_field» - это просто глупая логорея. (Нет, я не контролирую имя элемента; это чужая схема.) Должно быть много таких исключений, которые проверяют правило.
Марк Вуд,