Как в Python реализуются public, protected и private атрибуты

Ответ

В Python нет строгой инкапсуляции и модификаторов доступа (public, protected, private), как в Java или C++. Вместо этого используется соглашение об именовании для обозначения видимости атрибутов и методов.

  1. public (Публичный) Атрибуты без ведущих подчеркиваний. Они предназначены для свободного использования из любого места.

    self.name = "John"
  2. _protected (Защищенный) Атрибуты с одним ведущим подчеркиванием. Это соглашение для разработчиков, что атрибут предназначен для внутреннего использования в классе и его наследниках. Интерпретатор Python не накладывает никаких ограничений на доступ к нему.

    self._age = 30
  3. __private (Приватный) Атрибуты с двумя ведущими подчеркиваниями. Python применяет к таким именам механизм искажения имен (name mangling), преобразуя имя в _ИмяКласса__имя_атрибута. Это делает случайное обращение извне затруднительным, но не невозможным.

    self.__secret_code = "1234"

Пример:

class Person:
    def __init__(self, name, age, secret):
        self.name = name              # public
        self._age = age               # _protected
        self.__secret = secret        # __private

    def display(self):
        # Внутри класса есть доступ ко всем атрибутам
        print(f"Name: {self.name}, Age: {self._age}, Secret: {self.__secret}")

p = Person("Alice", 25, "qwerty")

# Доступ к атрибутам
print(p.name)                  # OK: 'Alice'
print(p._age)                  # OK, но не рекомендуется: 25

try:
    print(p.__secret)          # Ошибка: AttributeError
except AttributeError as e:
    print(e)

# Доступ к "приватному" атрибуту через искаженное имя
print(p._Person__secret)       # OK: 'qwerty'

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