все Python 3ООПпонятие
Инкапсуляция — _private, __mangled
инкапсуляция
Одиночный _ — соглашение (внутренний). Двойной __ — name mangling (переименование _Class__attr). Нет настоящих private в Python.
Синтаксис
self._protected
self.__private
Name mangling существует, чтобы подкласс случайно не перекрыл атрибут, а не чтобы что-то спрятать — до __attr всё равно можно дотянуться как obj._Class__attr. Оно не трогает dunder-имена вроде __init__ (с завершающим __), а одиночный _ вообще ничего не запрещает — это чистое соглашение.
Примеры
class BankAccount:
def __init__(self, balance):
self._balance = balance # 'protected'
def get_balance(self):
return self._balance
acc = BankAccount(100)
print(acc.get_balance()) # → 100
print(acc._balance) # → 100 (можно, но нежелательно)
class Secret:
def __init__(self):
self.__secret = 42
def reveal(self):
return self.__secret
s = Secret()
print(s.reveal()) # → 42
try:
s.__secret
except AttributeError as e:
print(e) # → 'Secret' object has no attribute '__secret'
print(s._Secret__secret) # → 42 — имя искажено, но доступно
# В наследовании __attr не переопределяется случайно
class Base:
def __init__(self):
self.__x = 'base'
def get_x(self):
return self.__x
class Child(Base):
def __init__(self):
super().__init__()
self.__x = 'child' # → _Child__x, не трогает _Base__x
def get_child_x(self):
return self.__x
ch = Child()
print(ch.get_x()) # → base
print(ch.get_child_x()) # → child
class Config:
_default = {'timeout': 30}
def __init__(self, **kwargs):
self._settings = {**self._default, **kwargs}
def get(self, key):
return self._settings.get(key)
cfg = Config(timeout=60)
print(cfg.get('timeout')) # → 60
# Конвенция: _ означает 'не трогай'
class Transformer:
def transform(self, data):
data = self._preprocess(data)
return self._process(data)
def _preprocess(self, data):
return [x.strip() for x in data]
def _process(self, data):
return [x.upper() for x in data]
t = Transformer()
print(t.transform([' hello ', ' world '])) # → ['HELLO','WORLD']
См. также
Открыть в полном глоссарииdocs.python.orgСообщить о неточности