'id' - це неправильне ім'я змінної в Python


141

Чому погано називати змінну idв Python?


33
Більшість людей додають підкреслення до ідентифікаторів, які зіштовхуються із вбудованими / ключовими словами: id_, map_, list_, filter_ тощо
cdleary

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було вилучено за один раз, але врешті вони вирішили не видаляти його. Я більше не можу редагувати свій оригінальний коментар, тому я видалю його, щоб у майбутньому не плутати людей.
Eli Courtwright

20
@EliCourtwright Я б хотів, щоб вони його зняли. Який погано названий метод! Загальна загальна назва, що використовується у тисячах місць (де контекст надає значення). Тож хтось вирішив використовувати його як глобальну назву там, де немає контексту?
Основні

2
Дивовижно, що власний підручник з виразів з Python Google ( developers.google.com/edu/python/regular-expressions ) використовує Google str = 'an example word:cat!!'. Чи є в когось із депутатів, що говорять, не робіть цього?
словазвідси

57

У PEP 8 - Посібник зі стилів для Python Code , наступні вказівки відображаються в розділі Описово: Імена стилів :

  • single_trailing_underscore_ : використовується умовно, щоб уникнути конфліктів із ключовим словом Python, наприклад

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

Отже, щоб відповісти на запитання, приклад, який застосовує цю інструкцію:

id_ = 42

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


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), і як говорить нам другий рядок «Дзен Питона» Тіма Пітерса :> Явне це краще, ніж неявне. Решту дивіться, запустивши:import this
Росс,

9
Я б все-таки уникав цього, якщо це взагалі можливо. Навіть якщо з будь-якої іншої причини, крім того, щоб не почути, як співробітники скаржаться. :-)
Джейсон Бейкер

1
Я повністю погоджуюся: називати змінну "id" у невеликій функції (і, таким чином, сферою), нешкідливо. Дуже мало людей використовують idвбудований у будь-якому випадку. Це сказало, що мені знадобилося певний час, коли колега переоцінив listвбудовану локальну змінну. Тож загальне правило, яке згадують інші, все ще має сенс.
silviot

5

Погано називати будь-яку змінну після вбудованої функції. Однією з причин є те, що це може заплутати читача, який не знає, що ім'я перекреслено.


2

id- це вбудована функція в Python. Призначення значення idбуде замінено функцію. Найкраще або додати префікс як у, some_idабо використовувати його з іншої великої літери, як у ID.

Вбудована функція приймає єдиний аргумент і повертає ціле число для адреси пам'яті об'єкта, який ви передали (в CPython).

>>> id(1)
9787760
>>> x = 1
>>> id(x)
9787760

2
зауважте, що ви можете назвати атрибут класу або метод "id", який не торкнеться вбудованої функції.
Тоні Ружа


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

Так? Де я намагаюся викликати інт? Це все вбудовані ...

Якби я назвав його badge_idабо id_, я б не мав цю проблему.


-6

Оскільки python - це динамічна мова, зазвичай не годиться давати однойменній змінній та функції однакову назву. id () - це функція в python, тому рекомендується не використовувати змінну з назвою id. Зважаючи на це, це стосується всіх функцій, які ви можете використовувати ... змінна не повинна мати те саме ім'я, що і функція.


3
"Оскільки python - це динамічна мова, зазвичай не годиться давати змінній та функції те саме ім'я." - Ви не можете надати змінній та функції те саме ім'я. Нічого спільного з тим, що це динамічна мова. Якщо ви маєте на увазі присвоєння властивостям тих самих імен, що й інші об'єкти в тому ж обсязі, я також не погоджуюся. У вас може бути клас під назвою "Ключ", екземпляр цього класу під назвою "ключ" та властивість іншого об'єкта, який називається "ключ", наприклад, "door.key".
Перрелл
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.