Что означает одиночное и двойное подчеркивание перед именем объекта?

1150
задан 16 revs, 10 users 50% 27 March 2019 в 14:24
поделиться

6 ответов

Одиночное подчеркивание

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

Цитата PEP-8 :

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

Двойное подчеркивание (изменение имени)

Из документы Python :

Любой идентификатор формы __ spam (не менее двух ведущих подчеркиваний, не более одного подчеркивания в конце) текстуально заменяется на _classname__spam , где имя класса - это имя текущего класса с подчеркивание (и) удалено. Это изменение выполняется без учета синтаксической позиции идентификатора, поэтому его можно использовать для определения частных экземпляров и переменных класса, методов, переменных, хранящихся в глобальных объектах, и даже переменных, хранящихся в экземплярах. закрытый для этого класса в экземплярах других классов.

И предупреждение с той же страницы:

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

Пример

>>> class MyClass():
...     def __init__(self):
...             self.__superprivate = "Hello"
...             self._semiprivate = ", world!"
...
>>> mc = MyClass()
>>> print mc.__superprivate
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
AttributeError: myClass instance has no attribute '__superprivate'
>>> print mc._semiprivate
, world!
>>> print mc.__dict__
{'_MyClass__superprivate': 'Hello', '_semiprivate': ', world!'}
1091
ответ дан 19 December 2019 в 20:15
поделиться

Пока отличные ответы, но некоторые лакомые кусочки отсутствуют. Одиночное подчеркивание в начале - не совсем просто соглашение: если вы используете из импорта foobar * , а модуль foobar не определяет __ all __ , имена, импортированные из модуля , не включают имена с начальным подчеркиванием. Допустим, это в основном соглашение, так как этот случай - довольно неясный угол; -).

Соглашение о начальном подчеркивании широко используется не только для частных имен, но также для чего C ++ будет называть защищенными - например, имена методов, которые полностью предназначены для переопределения подклассами (даже те, которые имеют , которые должны быть переопределены, поскольку в базовом классе они вызывают NotImplementedError ! -), часто встречаются с одним ведущим подчеркиванием имена для указания коду с использованием экземпляров этого класса (или подклассов), которые не предназначены для прямого вызова указанных методов.

Например, чтобы создать потокобезопасную очередь с другой дисциплиной организации очереди, чем FIFO, импортирует Queue, подклассы Queue.Queue и переопределяет такие методы, как _get и _put ; "клиентский код" никогда не вызывает эти ("ловушки") методы, а скорее ("организующий" ) общедоступные методы, такие как put и get (это известно как шаблон проектирования Template Method - см., например, здесь , чтобы узнать об интересном презентация, основанная на видео моего выступления на эту тему, с добавлением резюме стенограммы).

Правка: ссылки на видео в описании переговоров теперь не работают. Вы можете найти первые два видео здесь и здесь .

296
ответ дан 19 December 2019 в 20:15
поделиться

__ foo __ : это просто соглашение, способ для системы Python использовать имена, которые не будут конфликтовать с именами пользователей.

_foo : это просто соглашение, способ для программиста указать, что переменная является частной (что бы это ни значило в Python).

__ foo : это имеет реальное значение: интерпретатор заменяет это имя на _classname__foo как способ гарантировать, что имя не будет перекрываться с аналогичным именем в другом классе.

Никакая другая форма подчеркивания не имеет значения в мире Python.

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

282
ответ дан 19 December 2019 в 20:15
поделиться

Одинарное начало подчеркивание - это соглашение. нет никакой разницы с точки зрения интерпретатора, начинаются ли имена с одного символа подчеркивания или нет.

Двойные подчеркивания в начале и в конце используются для встроенных методов, таких как __ init __ , __ bool __ и т. Д.

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

5
ответ дан 19 December 2019 в 20:15
поделиться

Хороший вопрос, дело не только в методах. Функции и объекты в модулях обычно также имеют префикс с одним подчеркиванием и могут иметь префикс двух.

Но имена __double_underscore, например, не изменяются в модулях. Случается, что имена, начинающиеся с одного (или нескольких) символов подчеркивания, не импортируются, если вы импортируете все из модуля (из модуля import *), а также имена не отображаются в справке (модуль).

3
ответ дан 19 December 2019 в 20:15
поделиться

Accroding к https://dbader.org/blog/meaning-of-underscores-in-python

  • Единственный Начальный символ подчеркивания (_var) : Соглашение о присвоении имен, указывающее на имя, предназначено для внутреннего пользования. Обычно не осуществленный интерпретатором Python (кроме подстановочного импорта) и предназначенный как подсказка для программиста только.
  • Единственное Запаздывание Подчеркивания (var _) : Используемый условно для предотвращения конфликтов имен с ключевыми словами Python.
  • Двойной Начальный символ подчеркивания (__ var) : Триггерное искажение имени при использовании в контексте класса. Осуществленный интерпретатором Python.
  • Двойное Продвижение и Запаздывание Подчеркивания (__ var __) : Указывает на специальные методы, определенные языком Python. Избегайте этой схемы именования для своих собственных атрибутов.
  • Одинарное подчеркивание (_) : Иногда используемый в качестве названия временных или незначительных переменных (“don’t care”). Также: результат последнего выражения в REPL Python.
1
ответ дан 19 December 2019 в 20:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: