_имя). Предполагается, что они предназначены для внутреннего использования класса или его подклассов. Доступ к ним вне класса технически возможен, но считается плохой практикой.__имя). Python выполняет name mangling, заменяя __имя на _ClassName__имя, чтобы их сложнее было случайно использовать вне класса.  Доступ к ним все еще возможен, но сильно усложнен.В Python, инкапсуляция – это механизм сокрытия внутренних данных объекта от прямого доступа извне и объединения данных и методов, работающих с этими данными, в единый модуль. В отличие от некоторых других языков, Python не имеет строгой приватности, но предоставляет соглашения, которые указывают на то, какие атрибуты и методы класса предназначены для внутреннего использования.
Основная идея инкапсуляции:
Реализация инкапсуляции в Python:
Python реализует инкапсуляцию с помощью соглашений об именах:
my_attribute, my_method())._protected_attribute, _protected_method()).  Это соглашение говорит разработчикам, что к этим атрибутам и методам следует относиться как к внутренним, но Python не запрещает к ним доступ извне.__private_attribute, __private_method()). Python применяет name mangling (искажение имени) к таким атрибутам и методам, чтобы их было сложнее (но не невозможно) получить доступ к ним извне. Имя преобразуется в _ClassName__private_attribute.Пример:
class BankAccount:
    def __init__(self, account_number, balance):
        self.account_number = account_number  # Public
        self._balance = balance             # Protected
        self.__transaction_history = []  # Private
    def deposit(self, amount):
        if amount > 0:
            self._balance += amount
            self.__transaction_history.append(f"Deposit: +{amount}")
        else:
            print("Invalid deposit amount.")
    def withdraw(self, amount):
        if 0 < amount <= self._balance:
            self._balance -= amount
            self.__transaction_history.append(f"Withdrawal: -{amount}")
        else:
            print("Insufficient funds or invalid withdrawal amount.")
    def get_balance(self):
        return self._balance
    def __get_transaction_history(self): #Private Method
        return self.__transaction_history
    def print_transaction_history(self): #Public method, indirectly uses private member
        print(self.__get_transaction_history())
# Использование:
account = BankAccount("1234567890", 1000)
print(account.account_number)  # Доступно (публичный атрибут)
print(account.get_balance())     # Доступно через публичный метод
account.deposit(500)
account.withdraw(200)
account.print_transaction_history() # Access private member through public method
#print(account.__transaction_history) # AttributeError: 'BankAccount' object has no attribute '__transaction_history'
#print(account._BankAccount__transaction_history) # Works but not recommended!
  Важно: Несмотря на соглашения, Python позволяет получить доступ к "приватным" атрибутам и методам через name mangling. Однако, это считается плохой практикой, так как нарушает принципы инкапсуляции и может привести к непредсказуемому поведению программы. Цель инкапсуляции в Python – скорее указание на намерения разработчика, а не строгое принуждение.
В заключение, инкапсуляция в Python – это соглашение, основанное на соглашениях об именах, которое помогает разработчикам организовывать код, скрывать внутренние детали реализации и улучшать модульность и поддерживаемость.