_имя
). Предполагается, что они предназначены для внутреннего использования класса или его подклассов. Доступ к ним вне класса технически возможен, но считается плохой практикой.__имя
). 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 – это соглашение, основанное на соглашениях об именах, которое помогает разработчикам организовывать код, скрывать внутренние детали реализации и улучшать модульность и поддерживаемость.