В чем разница между одинарным и двойным подчеркиванием в Python

«В чем разница между одинарным и двойным подчеркиванием в Python» — вопрос из категории Python, который задают на 24% собеседований AQA / Automation. Ниже — развёрнутый ответ с разбором ключевых моментов.

Ответ

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

Одинарное подчеркивание (_name)

  • Семантика: "Защищенный" (protected) член. Это сигнал разработчику: "Этот атрибут/метод предназначен для внутреннего использования в классе или его подклассах. Не используйте его напрямую извне, если не понимаете последствий".
  • Поведение: Никаких технических ограничений. Доступ извне класса возможен.
  • Пример:

    
    class ApiClient:
    def __init__(self):
        self._base_url = "https://api.example.com"  # Защищенный атрибут
        self._session = requests.Session()
    
    def _make_request(self, endpoint):  # Защищенный метод
        return self._session.get(self._base_url + endpoint)

Доступ все равно возможен, но это не рекомендуется

client = ApiClient() print(client._base_url) # Работает, но нарушает соглашение


### Двойное подчеркивание (`__name`)
*   **Семантика:** Вызывает механизм **name mangling** (искажение имени). Цель — избежать случайных конфликтов имен в подклассах, а не обеспечить приватность.
*   **Поведение:** Интерпретатор изменяет имя атрибута внутри класса на `_ClassName__attribute`. Это делает доступ извне менее очевидным, но не невозможным.
*   **Пример:**
```python
class MyClass:
    def __init__(self):
        self.__private_value = 42  # Имя будет искажено

    def __private_method(self):    # Имя будет искажено
        return "secret"

obj = MyClass()
# Прямой доступ не сработает
# print(obj.__private_value)  # AttributeError

# Но доступ через искаженное имя возможен
print(obj._MyClass__private_value)  # Выведет 42
print(obj._MyClass__private_method())  # Выведет 'secret'

Для тестировщика (QA): При написании модульных или интеграционных тестов на Python:

  1. Обычно тестируют только публичный интерфейс (методы без подчеркиваний).
  2. Если необходимо протестировать внутреннюю логику, обращаются к защищенным (_) методам, осознавая хрупкость таких тестов.
  3. К методам с двойным подчеркиванием (__) обращаться напрямую в тестах крайне не рекомендуется — это нарушает инкапсуляцию, задуманную разработчиком, и такие тесты будут ломаться при любом рефакторинге.