'id' - неправильное имя переменной в Python

141

Почему плохо назвать переменную idв Python?

Брайан Бак
источник
33
Большинство людей добавляют подчеркивание к идентификаторам, которые конфликтуют со встроенными / ключевыми словами: id_, map_, list_, filter_ и т. Д.
cledary
3
Более подлым решением было бы использование переменной ID.
Симон Куанг
46
Лучший вопрос был бы ... Какой гений думал, что использование такого общего, обобщенного имени для встроенной функции было хорошей идеей?
Базовый

Ответы:

143

id() является фундаментальным встроенным:

Помощь по встроенной функции idв модуле __builtin__:

id(...)

    id(object) -> integer

    Return the identity of an object.  This is guaranteed to be unique among
    simultaneously existing objects.  (Hint: it's the object's memory
    address.)

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

Кевин Литтл
источник
3
Хорошо, для 'id' вы правы, но комментарий "в общем ..." по-прежнему применяется, не так ли?
Кевин Литтл
5
Я бы, конечно, избежал этого для глобалов модулей. Для переменных, ограниченных локальной областью, так что вы можете видеть, что одной и той же функции не нужно будет использовать встроенную функцию, это не то, о чем я бы беспокоился.
bobince
@Caramdir: Хороший улов, idбыл намечен для удаления в одно время, но в конце концов они решили не удалять его. Я больше не могу редактировать свой оригинальный комментарий, поэтому я удалю его, чтобы не запутать людей в будущем.
Эли Кортрайт,
20
@ EliCourtwright Я бы хотел, чтобы они его убрали. Какой плохо названный метод! Общее, общее имя, используемое в тысячах мест (где контекст дает значение). Таким образом, кто-то решил использовать это как глобальное имя, где нет контекста?
Базовые
2
Удивительно, но используется собственный учебник Google по регулярным выражениям Python ( developers.google.com/edu/python/regular-expressions ) str = 'an example word:cat!!'. Есть ли что-нибудь в PEP, которое говорит, что не делай этого?
словами
57

В PEP 8 - Руководство по стилю для кода Python в разделе « Описательный» появляется следующее руководство : Стили именования :

  • single_trailing_underscore_ : используется по соглашению, чтобы избежать конфликтов с ключевым словом Python, например

    Tkinter.Toplevel(master, class_='ClassName')

Итак, чтобы ответить на вопрос, пример, который применяет это руководство:

id_ = 42

Включение завершающего подчеркивания в имя переменной проясняет намерение (для тех, кто знаком с руководством в PEP 8).

DavidRR
источник
1
Это не дает ответ на актуальный вопрос, но +1 для PEP-8 именования
Эге
Хороший совет, но idэто встроенное, а не ключевое слово, и это не объясняет, почему плохо скрывать встроенное.
wjandrea
51

idявляется встроенной функцией, которая дает идентификатор объекта (который также является адресом его памяти в CPython). Если вы назовете одну из своих функций id, вам придется сказать, builtins.idчтобы получить оригинал (или __builtins__.idв CPython). Глобальное переименование idсбивает с толку во всем, кроме небольшого сценария.

Однако повторное использование встроенных имен в качестве переменных не так уж и плохо, если их использование локально. В Python есть много встроенных функций, которые (1) имеют общие имена и (2) вы не будете много использовать в любом случае. Использование их в качестве локальных переменных или в качестве членов объекта - это нормально, поскольку из контекста очевидно, что вы делаете:

Пример:

def numbered(filename):
    with open(filename) as file:
        for i, input in enumerate(file):
            print("%s:\t%s" % (i, input), end='')

Некоторые встроенные модули с заманчивыми именами:

  • id
  • file
  • list, dict
  • map
  • all, any
  • complex, int
  • dir
  • input
  • slice
  • buffer
  • sum
  • min, max
  • object
Натан Шивели-Сандерс
источник
8
PEP 8 , который был обновлен 01 августа 2013 года, теперь рекомендует избегать путаницы, просто добавляя _имя переменной. Пожалуйста, смотрите мой ответ .
DavidRR
1
Стоит отметить, что idфункция, возвращающая адрес памяти объекта, является деталью реализации CPython. Также стоит отметить, что функция требуется только для того, чтобы возвращать другое число для любых двух существующих объектов. Если объект собирается мусором, его идентификатор может быть переработан.
Зак Крис
@ Zac Спасибо! Я отредактировал ответ, чтобы добавить этот пункт об адресе памяти и ссылку, чтобы люди могли читать больше.
wjandrea
42

Я мог бы сказать кое-что непопулярное здесь: id()это довольно специализированная встроенная функция, которая редко используется в бизнес-логике. Поэтому я не вижу проблемы в использовании его в качестве имени переменной в точной и хорошо написанной функции, где ясно, что id не означает встроенную функцию.

Себастьян Риттау
источник
1
В ответ на:> id это довольно специализированная встроенная> функция, которая редко используется в> бизнес-логике. Поэтому я не вижу> проблемы в использовании его в качестве переменной> имени в точной и хорошо написанной> функции, тогда как ясно, что id> не означает встроенную функцию. Хотя это и правда, но, вероятно, было бы неплохо быть более конкретным с этим именем переменной, чем просто «id». У многих вещей есть идентификаторы (особенно если вы работаете с RDBMS), и, как говорит вторая строка Тима Питерса « Дзен Python» :> Явное лучше, чем неявное. Смотрите остальное, запустив:import this
Росс
9
Я все еще избегал бы этого, если вообще возможно хотя. Даже если по какой-то другой причине, кроме как не слышать, коллеги жалуются. :-)
Джейсон Бейкер
1
Я полностью согласен: наименование переменной "id" в маленькой функции (и, следовательно, в области видимости) безвредно. В idлюбом случае, мало кто использует встроенное. Тем не менее, мне потребовалось некоторое время, когда коллега переопределил listвстроенную переменную с локальной переменной. Так что общее правило, которое упоминают другие люди, все еще имеет смысл.
Сильвиот
5

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

Тони Ружа
источник
2

idэто встроенная функция в Python Присвоение значения idпереопределит функцию. Лучше либо добавить префикс как в, some_idлибо использовать его в другой заглавной букве, как в ID.

Встроенная функция принимает один аргумент и возвращает целое число для адреса памяти переданного вами объекта (в CPython).

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760
Брайан Бак
источник
2
обратите внимание, что вы можете назвать атрибут класса или метод 'id', который не будет касаться встроенной функции.
Тони Ружа
0

Потому что это имя встроенной функции.

ahockley
источник
0

Другие упоминали, что это сбивает с толку, но я хочу объяснить, почему . Вот пример, основанный на реальной истории. По сути, я пишу класс, который принимает idпараметр, но потом пытаюсь использовать встроенную функцию idпозже.

class Employee:
    def __init__(self, name, id):
        """Create employee, with their name and badge id."""
        self.name = name
        self.id = id
        # ... lots more code, making you forget about the parameter names
        print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))

tay = Employee('Taylor Swift', 1985)

Ожидаемый результат:

Created Employee 'Taylor Swift' at 0x7efde30ae910

Фактический вывод:

Traceback (most recent call last):
  File "company.py", line 9, in <module>
    tay = Employee('Taylor Swift', 1985)
  File "company.py", line 7, in __init__
    print('Created', type(self).__name__, repr(name), 'at', hex(id(self)))
TypeError: 'int' object is not callable

А? Где я пытаюсь вызвать Int? Это все встроенные ...

Если бы я назвал это badge_idили id_, у меня не было бы этой проблемы.

wjandrea
источник
-6

Поскольку python является динамическим языком, обычно не рекомендуется давать имя переменной и функции с одинаковым именем. id () - это функция в python, поэтому рекомендуется не использовать переменную с именем id. Учитывая это, это относится ко всем функциям, которые вы можете использовать ... переменная не должна иметь того же имени, что и функция.

Китти
источник
3
«Поскольку python - это динамический язык, обычно не стоит давать имя переменной и функции». - Вы не можете присвоить переменной и функции одно и то же имя. Ничего общего с тем, что это динамический язык. Если вы хотите присвоить свойствам те же имена, что и другим объектам в той же области, я также не согласен. У вас может быть класс с именем «Ключ», экземпляр этого класса с именем «ключ» и свойство другого объекта с именем «ключ», например, «door.key».
Purrell