Python Glossary English

все 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Сообщить о неточности