2010-08-02 6 views
62

Можно создать дубликат:
The meaning of a single- and a double-underscore before an object name in PythonЧастные переменные и методы в Python

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

+1

Спасибо всем. Я нашел другую тему, которая полезна. http://stackoverflow.com/questions/70528/why-are-pythons-private-methods-not-actually-private – kurikintoki

+1

Лучше: http://stackoverflow.com/questions/1301346/the-meaning-of-a- single-and-a-double-underscore-before-an-object-name-in-python – laffuste

ответ

33

Двойной знак подчеркивания. Он управляет именем таким образом, что к нему нельзя получить доступ только через __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 вместо этого. Но он кричит: «Я ЧАСТЬ НЕ СКАЗАЛ МЕНЯ», что лучше, чем ничего.

64

Обратите внимание, что в Python нет такого понятия, как «частный метод». Дважды Подчеркивание только имя коверкая:

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

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

EDIT, о путанице на __, PEP-8 совершенно ясно, что:

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

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

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

9

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

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

+7

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

-3

Потому что это соглашение о кодировании. См. here для получения дополнительной информации.

+4

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