Подтвердить что ты не робот

В чем разница в атрибутах python с подчеркиванием спереди и сзади

Возможный дубликат:
Значение одиночного и двойного подчеркивания перед именем объекта в Python

Я хочу знать, что отличает их в python

self._var1

self._var1_

self.__var1

self.__var1__

4b9b3361

Ответ 1

В качестве отправной точки вы, вероятно, найдете полезную цитату из PEP 8 - Руководство по стилю для кода Python:

Кроме того, следующие специальные формы с использованием ведущих или конечных признаются знаки подчеркивания (их обычно можно комбинировать с любыми случай конвенции):

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

single_trailing_underscore_: используется конвенцией, чтобы избежать конфликтов с ключевым словом Python, например. Tkinter.Toplevel(master, class_='ClassName')

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

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

Однако вы спросили в контексте атрибутов класса, поэтому рассмотрим ваши конкретные примеры:

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

Именование атрибута в вашем классе self._var1 указывает пользователю класса, к которому атрибут должен быть доступен только внутри класса (или, возможно, к подклассу), и что им не нужно напрямую обращаться к нему, и, вероятно, t изменить его. Вы должны использовать ведущие символы подчеркивания в тех же местах, в которых вы бы использовали поле private или protected в Java или С#, но имейте в виду, что язык фактически не обеспечивает принудительного доступа - вместо этого вы доверяете своему пользователю класса не делайте что-нибудь глупое и оставляйте им возможность доступа (или изменения) вашего частного частного поля, если они действительно, действительно уверены, что они знают, что они делают, и это имеет смысл.

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

self._var1_ - это не то, что я когда-либо видел. Я не думаю, что этот стиль именования имеет какое-либо общепринятое значение в мире Python.

Двойное подчеркивание

Это действительно имеет синтаксическое значение. Ссылаясь на self.__var1 из области вашего класса, вызывается name mangling. Из-за пределов вашего класса переменная будет выглядеть как self._YourClassName__var1 вместо self.__var1. Не все это используют - мы совсем не работаем - и для простых классов это похоже на слегка абсурдную и раздражающую альтернативу использованию одного ведущего подчеркивания.

Однако существует обоснование для его существования; если вы используете много наследования, если вы используете только одиночные подчеркивания, то у вас нет способа указать кому-то, читающему ваш код, разницу между переменными 'private' и 'protected' - те, которые даже не означают доступ к которым осуществляется подклассами, и подклассы могут получить доступ, но внешний мир может и не быть. Таким образом, использование единственного символа подчеркивания для обозначения "защищенный" и двойного подчеркивания, означающего 'private', может быть полезным соглашением в этой ситуации (и изменение имени позволит подклассам использовать переменную с тем же именем в своем подклассе, не вызывая столкновение).

Двумя ведущими и конечными символами подчеркивания

self.__var1__ - это то, что вы никогда не должны создавать, поскольку я его буквально написал, потому что стиль именования двойного ведущего и конечного подчеркивания предназначен для использования только для имен, которые имеют специальное значение, определенное Python, например, __init__ или __eq__ методов классов. Вы можете переопределить их, чтобы изменить поведение вашего класса (действительно, почти у всех классов будет определенный программист __init__), но вы не должны создавать свои собственные имена в этом стиле, например self.__var1__.