Если атрибут принадлежит обьекту и является приватным, то в атрибуте
__dict__ нему можно иметь доступ так:
pt = Point()
pt._Point__privateНо что дело до приватных методов ? Тут на самом дела все также обстоит,
есть 2 метода один приватный другой публичный, приставка в виде одного
underscore и названия Класса, поскольку каждый метод является по дефолту
статичным, то увидеть его можно в атрибуте __dict__ принадлежащем
классу, а не обьекту:
class Point:
def __init__(self, one, two):
self._list = one
self.__private = two
def my_public_method(self):
print('Публичный методв')
def __my_private_method(self):
print('Приватный методв')
pt = Point([10, 20, 30], "Приватная переменная")
Point.my_public_method(pt)
Point._Point__my_private_method(pt)
print(pt.__dict__)
print('='*20)
print(Point.__dict__)
# Вывод
#
# Публичный методв
# Приватный методв
# {'_list': [10, 20, 30], '_Point__private': 'Приватная переменная'}
# ====================
# {
# 'my_public_method':
# <function func6.<locals>.Point.my_public_method at 0x7fd3471f1d90>,
#
# '_Point__my_private_method':
# <function func6.<locals>.Point.__my_private_method at 0x7fd3471f1e18>,
# }Тут есть оба метода и как ожидалось приватный скрыт с помощью специального префикса.
Обычно существует 3 модификатора доступа к атрибутам обьектов, публичный используется по дефолту, один underscore делает атрибут защищенным, и 2 underscore дают приватность.
protected - не дает какого либо ограничения на доступ к атрибутам,
защищенность здесь номинальная, существует лишь как соглашение среди
программистов, не дает настоящей приватности.
private - тут есть настоящий механизм защиты атрибутов от внешнего
доступа, но есть одна хитрость.
Допустим есть такой класс:
class Point:
def __init__(self, x, y):
self.x = x
self._y = y
pt = Point(10, 20)
print("Point.__dict__ = ", Point.__dict__)
print("pt.__dict__ = ", pt.__dict__)Мы можем вывести атрибуты как обьекта так и класса, именно их
спец атрибут __dict__ который в виде словаря хранит в себе
все атрибуты.
У самого класса и у обьекта есть свои экземпляры этого атрибута.
Когда мы выводим __dict__ обьекта, то можем увидеть в нем наши
атрибуты, что мы задали при инициализации нового обьекта класса:
pt.__dict__ = {'x': 10, '_y': 20}Видим что все атрибуты тут и перечислены, что публичные, что защищенные, разница лишь в одном нижнем подчеркивании, теперь можно понять почему нет способа защиты от для protected атрибутов.
Добавим в наш класс новый атрибут __z и сделаем ее приватной,
тогда выведя __dict__ можно увидеть следующие:
class Point:
def __init__(self, x, y, z):
self.x = x
self._y = y
self.__z = z
pt = Point(10, 20, 30)
print("pt.__dict__ = ", pt.__dict__)
# Вывод
# pt.__dict__ = {'x': 10, '_y': 20, '_Point__z': 30}Мы назвали наш приватный атрибут как __z но в итоге видим как
появился атрибут _Point__z и уже вызвав этот атрибут мы можем
получить к нему доступ, даже несмотря на то, что он приватный.
print("pt._Point__z = ", pt._Point__z)
# Вывод
# pt._Point__z = 30Таким образом мы можем получать доступ к приватным атрибутам обьекта.
Создается при помощи одного нижнего подчеркивания, и говорит программисту, что этот атрибут следует использовать только внутри класса, или его дочерних классах, но по факту это никак не ограничивает доступ к атрибуту, и обращаться к нему можно из вне.
Данный модификатор просто декоративный.