Skip to content

Latest commit

 

History

History
144 lines (107 loc) · 5.71 KB

File metadata and controls

144 lines (107 loc) · 5.71 KB

Доступ к приватным атрибутам и методам обьекта

Если атрибут принадлежит обьекту и является приватным, то в атрибуте __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>,
    # }

Тут есть оба метода и как ожидалось приватный скрыт с помощью специального префикса.


Отсутствие настоящей защищенности/приватности в Python

Обычно существует 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

Таким образом мы можем получать доступ к приватным атрибутам обьекта.


Модификатор доступа protected

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

Данный модификатор просто декоративный.