Прямое обращение извне к защищённым или приватным методам/атрибутам класса нарушает инкапсуляцию и может привести к неожиданным последствиям. Для получения доступа к таким методам и атрибутам необходимо создавать отдельные методы.


Пример

Плохо:


class ExampleClass:
    def __init__(self):
        self._protected_attribute = 'I am protected'

    def _protected_method(self):
        return 'This is a protected method'


obj = ExampleClass()
protected_method = obj._protected_method()
protected_attribute = obj._protected_attribute

Хорошо:


class ExampleClass:
    def __init__(self):
        self._protected_attribute = 'I am protected'

    def _protected_method(self):
        return 'This is a protected method'

    def get_protected_method(self):
        return self._protected_method

    def get_protected_attribute(self):
        return self._protected_attribute


obj = ExampleClass()
protected_method_callback = obj.get_protected_method()
protected_attribute = obj.get_protected_attribute()