Подчеркивание против двойного подчеркивания с переменными и методами

Кто-то был достаточно хорош, чтобы объяснить мне, что __method() управляет, но вместо того, чтобы беспокоить его дальше, так как есть много других людей, которым нужна помощь, мне было интересно, сможет ли кто-нибудь еще разобраться в различиях.

Например, я не нуждаюсь в mangling, но не остаюсь приватным, чтобы кто-то не мог выполнить instance._method()? Или это просто заставляет его переписывать другую переменную, делая ее уникальной? Мне не нужны мои внутренние методы "скрытые", но поскольку они предназначены для использования, я не хочу, чтобы они использовались вне класса.

Ответ 1

От PEP 8:

  • _single_leading_underscore: слабый индикатор "внутреннего использования". Например.

    from M import *

    не импортирует объекты, имя которых начинается с подчеркивания.

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

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

  • __double_leading_underscore: при присвоении имени атрибуту класса вызывается имя   (внутри класса FooBar, __boo становится _FooBar__boo, см. ниже).

  • __double_leading_and_trailing_underscore__: "магические" объекты или   атрибуты, которые находятся в управляемых пользователем пространствах имен. Например. __init__  __import__ или __file__. Никогда не изобретайте такие имена; использовать их только   как задокументировано.

Кроме того, от Дэвида Гудгера Код как Pythonista:

Атрибуты: interface, _internal, __private

Но старайтесь избегать формы __private. Я никогда не использую его. Доверьтесь мне. если ты используйте его, вы пожалеете об этом позже.

Пояснение:

Люди, идущие с фона С++/Java, особенно подвержены чрезмерное использование/неправильное использование этой "функции". Но имена __private не работают. так же, как в Java или С++. Они просто запускают имя, которое целью является предотвращение случайных конфликтов пространства имен в подклассах: MyClass.__private просто становится MyClass._MyClass__private. (Обратите внимание, что даже это ломается для подклассов с тем же именем, что и суперкласса, например. подклассы в разных модулях.) Можно доступ __private к именам за пределами их класса, просто неудобно и хрупкий (он добавляет зависимость от точного имени суперкласса).

Проблема заключается в том, что автор класса может законно думать "это имя атрибута/метода должно быть закрытым, доступным только изнутри это определение класса" и использовать соглашение __private. Но позже, пользователь этого класса может сделать подкласс, который законно необходим доступ к этому имени. Так что либо надкласс должен быть изменен (что может быть сложно или невозможно), или код подкласса должен используйте ручные искаженные имена (что в лучшем случае уродливо и хрупко).

В Python есть концепция: "Мы все соглашаем взрослых здесь". Если вы используете форму __private, с которой вы защищаете атрибут? Подклассы должны использовать атрибуты из суперклассов должным образом, и ответственность за суперклассы правильно документируйте их атрибуты.

Лучше использовать соглашение с одним ведущим-подчеркиванием, _internal. "Это совсем не имя, а просто указывает на другие, чтобы" быть осторожными с этим, это внутренняя реализация деталь; не трогайте его, если вы не понимаете его полностью ". хотя.

Ответ 2

Единственное ведущее подчеркивание - это просто соглашение, которое означает: "Вы, вероятно, не должны использовать это". Это не делает ничего, чтобы остановить использование атрибута.

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

Ответ 3

В Python отсутствует контроль доступа. Вы можете получить доступ ко всем атрибутам класса и включать в себя искаженные имена (как _class__variable). Сосредоточьтесь на своем коде и API вместо того, чтобы пытаться защитить разработчиков от себя.