Правильно ли добавлять нижнее подчеркивание к приватному полю при наличии сеттера/геттера

Есть пример класса с приватным полем и сеттером/геттером (isinstance исключительно для демонстрации):

class MyClass:

    def __init__(self, custom_private_field):   
        self._custom_private_field = custom_private_field  # self field with underscore

    @property
    def custom_private_field(self) -> str:
        return self._custom_private_field

    @custom_private_field.setter
    def custom_private_field(self, custom_private_field):
        if not isinstance(custom_private_field, str):
            raise AttributeError("message")
        self._custom_private_field = custom_private_field

Если я пытаюсь создать объект, указав значение custom_private_field отличное от str:

print(MyClass(custom_private_field=5))

то никакой ошибки не получаю (ожидаю AttributeError). Если же убрать нижнее подчеркивание в __init__:

class MyClass:

    def __init__(self, custom_private_field):   
        self.custom_private_field = custom_private_field  # self field without underscore

    @property
    def custom_private_field(self) -> str:
        return self._custom_private_field

    @custom_private_field.setter
    def custom_private_field(self, custom_private_field):
        if not isinstance(custom_private_field, str):
            raise AttributeError("message")
        self._custom_private_field = custom_private_field

то проверка в сеттере будет проведена и будет выдана ошибка AttributeError.

Как правильно указать private поле с проверкой его значения?


Ответы (1 шт):

Автор решения: Artem S. Zhelonkin

Из разбора вопроса про pythonic способ использования getters/setters Aaron Hall достаточно подробно рассмотрел заданный мной вопрос, в частности, он приводит следующий пример (внёс небольшие изменения для наглядности):

class Protective(object):
    
    def __init__(self, start_protected_value=0):
        self.protected_value = start_protected_value
    
    @property
    def protected_value(self):
        return self._protected_value
    
    @protected_value.setter
    def protected_value(self, value):
        if not (0 <= value <= 100):
            raise ValueError("protected_value must be " +
                             "between 0 and 100 inclusive")
        self._protected_value = int(value)

В данном примере можно заметить, что отсутствует underscore перед protected_value и приводится проверка данного поля в setter. В моём случае, это работает прекрасно. Надеюсь, что кому-либо это будет также полезно.

→ Ссылка