Яке призначення єдиної змінної підкреслення "_" в Python?


618

Яке значення має _після forв цьому коді?

if tbh.bag:
   n = 0
   for _ in tbh.bag.atom_set():
      n += 1


5
У вашому випадку було б чистіше len(tbh.bag.atom_set())(якщо повернене значення має __len__метод) абоsum(1 for _ in tbh.bag.atom_set())
Nick T

В pylintіншому варіанті для фіктивних імен змінних є префікс dummy_імені змінної. Використання цього префіксу з pylint, pylintне робить попередження. Також ви можете налаштувати схему змінної манекена для pylintрозміщення таких речей __.
Тревор Бойд Сміт

Відповіді:


780

_ має 4 основних традиційних напрямків використання в Python:

  1. Втримати результат останнього виконаного виразу (/ заяви) в сесії інтерактивного перекладача. Цей прецедент встановив стандартний перекладач CPython, і інші перекладачі пішли за цим прикладом
  2. Для пошуку перекладу в i18n (див. Документацію gettext, наприклад), як у коді типу: raise forms.ValidationError(_("Please enter a correct username"))
  3. В якості загального призначення «холостим» ім'я змінної , щоб вказати , що частина результату функції буде свідомо ігнорується (Концептуально, він буде відкинутий.), Так як в коді , як: label, has_label, _ = text.partition(':').
  4. Як частина визначення функції (використовуючи або defабо lambda), де підпис фіксований (наприклад, API зворотного виклику або API батьківського класу), але для цієї конкретної реалізації функції не потрібні всі параметри, як у коді типу:callback = lambda _: True

(Тривалий час у цій відповіді були перелічені лише перші три випадки використання, але четвертий випадок траплявся досить часто, як зазначалося тут , для того, щоб його варто було чітко перелічити)

Останнє "назва змінної змінної або параметра" використовує випадки, можуть суперечити випадку використання пошуку пошуку, тому слід уникати використання _як перемінної змінної у будь-якому кодовому блоці, який також використовує її для перекладу i18n (багато людей вважають за краще подвійне підкреслення , __як їх перекидну змінну саме з цієї причини).


19
Чи можете ви пояснити, як це працює у виклику функції, наприклад: підвищити форми.ValidationError (_ ("Будь ласка, введіть правильне ім'я користувача")) . Я бачив це в коді Джанго, і не ясно, що відбувається.
Джон С

41
Це використання 2 - за домовленістю _- це ім'я, яке використовується для функції, яка здійснює пошуки трансляції інтернаціоналізації та локалізації рядків. Я впевнений, що ця gettextбібліотека встановила цю конвенцію.
ncoghlan

43
FWIW, я особисто почав використовувати __(подвійне підкреслення) як мою змінну загального призначення, щоб уникнути конфлікту з будь-яким із перших двох випадків використання.
ncoghlan

14
Народні конвенції громади, як правило, не мають авторитетних джерел - лише спостереження за звичаями, що з’явилися з часом. FWIW, я один із співавторів останніх оновлень PEP 8, і моя відповідь ґрунтується на трьох різних способах, які я бачив, _як використане ім'я змінної, оскільки я почав професійно використовувати Python у 2002 році.
ncoghlan

12
У основному це стосується розпакування кортежу: одразу a, __, c = iterableповідомляє читачеві, що ми розпаковуємо 3-кортеж, але використовуємо лише перше та останнє значення. Якщо ми замість того, щоб писати a, b, c = iterable, читач (або автоматизований код Лінтера) можна розумно очікувати , що все a, bі cбуде використовуватися в подальшому (і якщо це не так , це може бути ознакою помилка де - то).
ncoghlan

207

Це просто ім'я змінної, і звичайне в python використовувати _для викидних змінних. Це просто вказує, що змінна циклу насправді не використовується.


5
ви маєте на увазі, що він не представляє останнього повернутого значення?
alwbtc

31
@steve тільки в оболонці
Габі Пуркару

4
подібний до використання _ в Prolog
Маттіас

3
подібне до використання ~ in Matlab
PatriceG

Зауважте, що в оболонці cpython, якщо ви чітко визначаєте _, вона постійно припиняє утримувати вихідне значення попереднього виразу. Це здається жахливо непослідовним, і стандарти стандарту Python lang повинні вирішити це питання. Вони повинні просто визначити _ім'я, що викидається, і не дозволяти йому використовуватись як реальний ідентифікатор.
theferrit32

78

Підкреслення _вважається змінною " Мені все одно " або " Throwaway "

  • Інтерпретатор python зберігає останнє значення виразу до спеціальної змінної, що називається _.

    >>> 10 
    10
    
    >>> _ 
    10
    
    >>> _ * 3 
    30
  • Підкреслення _також використовується для ігнорування конкретних значень. Якщо конкретні значення вам не потрібні або значення не використовуються, просто призначте значення підкреслення.

    Ігноруйте значення при розпакуванні

    x, _, y = (1, 2, 3)
    
    >>> x
    1
    
    >>> y 
    3

    Ігноруйте індекс

    for _ in range(10):     
        do_something()

2
Є третє використання, яке призначене для функції інтернаціоналізації _("Hello world!").
Джефф Юнкер

3
На рівні процесора, чи є насправді різниця між "для _ в діапазоні" і "для x в діапазоні", а потім не використовується x? Або це просто для читабельності людини?
iammax

1
@iammax Використовуючи disмодуль, я виявив, що байтового коду немає різниці. Переваги людської читабельності очевидні.
Alistair Carscadden

21

Існує 5 випадків використання підкреслення в Python.

  1. Для зберігання значення останнього виразу в інтерпретаторі.

  2. За ігнорування конкретних значень. (так званий "Мені все одно")

  3. Надати особливі значення та функції для назви змінних чи функцій.

  4. Використовувати як функції "Інтернаціоналізація (i18n)" або "Локалізація (l10n)".

  5. Розділити цифри числового значення.

Ось приємна стаття з прикладами компанії mingrammer .


2
Насправді це досить новий blog.pythonlibrary.org/2017/01/11/…
MichaelChirico

3

Що стосується мов Python, то _він не має особливого значення. Це дійсний ідентифікатор, як _foo, foo_або _f_o_o_.

Будь-яке особливе значення _має виключно умова. Кілька випадків поширені:

  • Ім’я манекена, коли змінна не планується використовувати, але ім'я вимагається за синтаксисом / семантикою.

    # iteration disregarding content
    sum(1 for _ in some_iterable)
    # unpacking disregarding specific elements
    head, *_ = values
    # function disregarding its argument
    def callback(_): return True
  • Багато REPLs / оболонок зберігають результат останнього виразу верхнього рівня в builtins._.

    Спеціальний ідентифікатор _використовується в інтерактивному перекладачі для зберігання результатів останньої оцінки; він зберігається в builtinsмодулі. Якщо він не знаходиться в інтерактивному режимі, _не має особливого значення і не визначений. [ джерело ]

    Завдяки способу пошуку імен, якщо тільки вони не затінюються глобальним або локальним _визначенням, на яке _йдеться builtins._.

    >>> 42
    42
    >>> f'the last answer is {_}'
    'the last answer is 42'
    >>> _
    'the last answer is 42'
    >>> _ = 4  # shadow ``builtins._`` with global ``_``
    >>> 23
    23
    >>> _
    4

    Примітка. Деякі оболонки, такі як ipythonне присвоєні, builtins._а окремі регістри _.

  • У контексті інтернаціоналізація та локалізація _використовується як псевдонім для функції первинного перекладу.

    gettext.gettext (повідомлення)

    Поверніть локалізований переклад повідомлення на основі поточного глобального домену, мови та локального каталогу. Ця функція зазвичай псевдонімічна як _ () у локальному просторі імен (див. Приклади нижче).

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.