Вопрос по private, python, private-members, private-methods – Закрытые переменные и методы в Python [дубликаты]

65

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

Что я должен использовать _foo (подчеркивание) или __bar (двойное подчеркивание) для закрытых членов и методов в Python?

Спасибо вам всем. Я нашел другую тему, которая полезна.stackoverflow.com/questions/70528/... kurikintoki

Ваш Ответ

4   ответа
9

Двойное подчеркивание. Это искажает имя. К переменной все еще можно получить доступ, но обычно это плохая идея.

Используйте одиночные подчеркивания для полуприватных (говорит разработчикам Python «только изменяйте это, если вам абсолютно необходимо») и удваивает для полностью закрытых.

Не совсем верно. Одно подчеркивание означает, что вы изменяете недокументированные свойства объекта, которые могут быть изменены, и вы вполне можете нарушить инварианты, поддерживаемые объектом, поэтому вы должны точно понимать, что вы делаете, если решите нарушить инкапсуляцию объекта. msw
67

Обратите внимание, что в Python нет такой вещи, как «закрытый метод». Двойное подчеркивание это просто название искажения:

>>> class A(object):
...     def __foo(self):
...         pass
... 
>>> a = A()
>>> A.__dict__.keys()
['__dict__', '_A__foo', '__module__', '__weakref__', '__doc__']
>>> a._A__foo()

И потому__ Префикс полезен, когда вам нужно, чтобы произошла искажение, например, чтобы не конфликтовать с именами вверх или вниз по цепочке наследования. Для других целей лучше использовать одиночное подчеркивание, ИМХО.

РЕДАКТИРОВАТЬ, относительно путаницы на__, РЕР-8 Совершенно ясно, что

Если ваш класс предназначен для использования в подклассах, и у вас есть атрибуты, которые вы не хотите использовать в подклассах, рассмотрите возможность присвоения им имен с двойным нижним подчеркиванием и без завершающего подчеркивания. Это вызывает алгоритм искажения имени Python, где имя класса искажается в имя атрибута.Это помогает избежать конфликтов имен атрибутов, если подклассы непреднамеренно содержат атрибуты с одинаковыми именами.

Примечание 3: не всем нравится искажение имени. Постарайтесь уравновесить необходимость избегать случайных конфликтов имен с потенциальным использованием продвинутыми абонентами.

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

-4

Потому что это соглашение о кодировании. УвидетьВот для большего.

ОП спрашивал, какой из них использовать. Не почему. Ponkadoodle
36

Двойное подчеркивание. Он искажает имя таким образом, что к нему нельзя получить доступ просто через__fieldName снаружи класса, с чего вы хотите начать, если они будут частными. (Хотя все еще не очень сложно получить доступ к полю.)

class Foo:
    def __init__(self):
        self.__privateField = 4;
        print self.__privateField # yields 4 no problem

foo = Foo()
foo.__privateField
# AttributeError: Foo instance has no attribute '__privateField'

Это будет доступно через_Foo__privateField вместо. Но он кричит «Я ЧАСТНЫЙ, НЕ ТРОГАЙ МНЕ», что лучше, чем ничего.

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