В этой статье вы узнаете все, что вам нужно знать о модификаторах/спецификаторах доступа в Python. Независимо от языка эта концепция играет жизненно важную роль в программировании.

Как следует из названия, «модификаторы доступа» указывают, какой уровень доступа для определенного атрибута или метода должен быть в классе. По сути, большинство языков имеют 3 уровня модификаторов доступа.

  1. Общественный
  2. Защищено
  3. Частный

А также в большинстве языков есть ключевые слова для конкретного модификатора доступа, чтобы строго определить уровень доступа. Но у python нет строгого способа или какого-либо ключевого слова для этого. Python имеет только соглашение для этого. Итак, как мы используем модификатор доступа в python? Давайте посмотрим один за другим.

Общий доступ Модификатор

В этом нет ничего особенного, и к нему можно получить доступ из любой точки программы. Если вы определяете атрибут без одного или нескольких _ (подчеркивания) в начале, он по умолчанию будет общедоступным.

Модификатор защищенного доступа

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

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

class Parent:
    _status = "I am protected"      # Protected attribute

    def _get_status(self):  # Protected method
        # Accessing protected attribute within the class is OK.
        return self._status
    
    def print_status(self): # Public method
        # Accessing protected attribute within the class is OK.
        print(self._status)

class Child(Parent):
    def print_name(self):   # Public method
        # Accessing protected method from child class is OK.
        print(self._get_status())

parent = Parent()
child = Child()

# Accessing protected attribute _status within the class (Recommended).
parent.print_status()

# Accessing protected method _get_status outside the class (Not Recommended).
print(parent._get_status())

# Accessing protected attribute _status outside the class (Not Recommended).
print(Parent._status)

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

Модификатор частного доступа

В Python закрытые члены определяются двумя символами подчеркивания в начале и не должны иметь двух или более знаков подчеркивания в конце.

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

class Parent:
    __status = "I am private"      # private attribute

    def __get_status(self):  # Private method
        # Accessing private attribute within the class is OK.
        return self.__status
    
    def print_status(self): # Public method
        # Accessing private attribute within the class is OK.
        print(self.__status)

class Child(Parent):
    def print_name(self):   # Public method
        # Accessing private method from child will generate an error.
        print(self.__get_status())

parent = Parent()
child = Child()

# Accessing private attribute __status within the class is ok.
parent.print_status()

# Accessing private method __get_status outside the class,
# will generate an error
print(parent.__get_status())

Когда мы пытаемся получить доступ к защищенным членам извне класса, это не приводит к ошибке. Но в приведенном выше примере, когда мы пытаемся получить доступ к частному члену в последней строке кода, это сгенерирует AttributeError. Почему так? Действительно ли частные члены являются частными в Python?

Конечно, нет. Даже если python генерирует ошибку при доступе к закрытым членам вне класса, они еще не защищены. Причина, по которой мы получаем сообщение об ошибке, заключается в том, что Python выполняет операцию над закрытыми членами, которая называется Изменение имен. Давайте посмотрим, что он делает.

Изменение имени в Python

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

_‹ClassName›‹Атрибут или имя метода›

Давайте посмотрим пример.

class MyClass:
    __status = "I am private"   # private attribute

    def __get_status(self):  # private method
        print(self.__status)

Теперь, если мы посмотрим на пространство имен вышеуказанного класса с помощью dir(MyClass), оно будет выглядеть примерно так.

['_MyClass__get_status', '_MyClass__status', '__class__', '__delattr__', '__dict__', '__dir__',
'__doc__', '__eq__' , '__format__', '__ge__', '__getattribute__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__le__', '__lt__', '__module__', '__ne__', '__new__', ' __reduce__', '__reduce_ex__', '__repr__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', '__weakref__']

Как видите, __get_status_изменился на _Parent__get__status_, а __statusизменился на _Parent__status. Итак, Python на самом деле не сделал вещи приватными, а изменил пространство имен в другой формат. Это называется «Изменение имени».

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

cls = MyClass()

# Accessing private members with mangled names,
# will not generate an error.
cls._MyClass__get_status()
cls._MyClass__status

# Accessing private members with defined names,
# will generate errors
cls.__status
cls.__get_status()

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

Итак, в Python модификаторы доступа — это всего лишь некоторые соглашения. Вы не ограничены строго для доступа к любому из этих уровней доступа. Но рекомендуется всегда следовать этим соглашениям, чтобы писать лучшие коды Python.

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