Почему «приватные» методы Python на самом деле не приватны? - PullRequest
603 голосов
/ 16 сентября 2008

Python дает нам возможность создавать «закрытые» методы и переменные внутри класса, добавляя к имени двойные подчеркивания, например: __myPrivateMethod(). Как же тогда это объяснить

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()
>>> obj.myPublicMethod()
public method
>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'
>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']
>>> obj._MyClass__myPrivateMethod()
this is private!!

В чем дело?!

Я немного объясню это тем, кто не совсем понял.

>>> class MyClass:
...     def myPublicMethod(self):
...             print 'public method'
...     def __myPrivateMethod(self):
...             print 'this is private!!'
... 
>>> obj = MyClass()

Я создал класс с открытым и закрытым методами и создал его.

Далее я вызываю его публичный метод.

>>> obj.myPublicMethod()
public method

Далее я пытаюсь вызвать его закрытый метод.

>>> obj.__myPrivateMethod()
Traceback (most recent call last):
  File "", line 1, in 
AttributeError: MyClass instance has no attribute '__myPrivateMethod'

Здесь все выглядит хорошо; мы не можем это назвать. На самом деле это «частный». Ну, на самом деле это не так. Запуск dir () на объекте открывает новый магический метод, который python волшебным образом создает для всех ваших «приватных» методов.

>>> dir(obj)
['_MyClass__myPrivateMethod', '__doc__', '__module__', 'myPublicMethod']

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

>>> obj._MyClass__myPrivateMethod()
this is private!!

Так много для инкапсуляции, а?

В любом случае, я всегда слышал, что Python не поддерживает инкапсуляцию, так зачем даже пытаться? Что дает?

Ответы [ 12 ]

2 голосов
/ 27 апреля 2018

Самая важная забота о закрытых методах и атрибутах - это сказать разработчикам, чтобы они не вызывали его вне класса, а это инкапсуляция. можно неправильно понять защиту от инкапсуляции. когда кто-то намеренно использует синтаксис, подобный тому, который вы упомянули ниже, вы не хотите инкапсуляции.

obj._MyClass__myPrivateMethod()

Я перешел с C #, и сначала это тоже было странно для меня, но через некоторое время я пришел к мысли, что только то, как дизайнеры кода Python думают об ООП, отличается.

0 голосов
/ 14 января 2019

Почему «приватные» методы Python на самом деле не приватны?

Насколько я понимаю, они не могут быть частными. Как обеспечить конфиденциальность?

Очевидный ответ: «Закрытые члены могут быть доступны только через self», но это не сработает - self не является особенным в Python, это не более чем общеупотребительное имя для первого параметра функции.

...