Страницы

Поиск по вопросам

четверг, 2 января 2020 г.

Не работает сильно приватное свойство в Python3 через __свойство, подскажите?

#python #python_3x


Изучаю Python3, дошел до инкапсуляции и тут я не могу понять.
Если правильно понял, то __ у свойства класса говорит о том, что напрямую к этому
методу обратиться через obj.__variable нельзя, правильно?

Но у меня не получается сделать приватным свойство, пробовал и через __init__(),
и просто в теле класса __ создавать.

Через сеттер-геттер нормально работает, но и напрямую через obj.__variable могут
изменять и считывать значение.

Скажите пожалуйста, где я ошибся?
Не хочется идти дальше, не поняв этой важной темы.

Код:

# Создаем класс Auto
class Auto:
    # Инициализация
    def __init__(self):
        self.__number = ""
        print("Создали класс Auto")

    # Свойства
    # Номер автомобиля, сильно приватное свойство, т.к. __ префикс и обратиться напрямую
нельзя через obj.__свойство
    #__number = ""

    # Сеттер
    def set_number(self, number):
        # Валидация данных
        if len(number) in [7, 8]:
            self.__number = number
        else:
            print("Номер автомобиля неправильный, задайте 7 или 8 цифр.")
    # Геттер
    def get_number(self):
        return self.__number

# Создаем объект Audi
audi = Auto()

# Задаем значение audi.__number через сеттер и считываем через геттер
audi.set_number("A777SD77")
print(audi.get_number())

# Пытаемся задать или прочитать свойство с сильной приватностью __number напрямую
- нельзя, т.к. сильно приватное
audi.__number = "L123OX23"
print(audi.__number)

# Считываем значение изначального __number через геттер, а не созданного извне _Auto__number,
оно не изменилось
print(audi.get_number())


Результат:

Создали класс Auto
A777SD77
L123OX23

Process finished with exit code 0

    


Ответы

Ответ 1



Это происходит потому, что на предпоследней строке (audi.__number = …) вы создаёте новый атрибут извне, точное имя которого __number. Созданный вами атрибут __number изнутри класса на самом деле получает имя _Auto__number, что как раз и является показателем приватности. Приватные атрибуты это не жёсткое правило, а просто соглашение. Если по каким-то причинам нужно получить доступ к такому атрибуту, то программист может это сделать. Подробнее: https://docs.python.org/3/tutorial/classes.html#private-variables

Ответ 2



На будущее чтобы таких вопрос не возникало используйте __dict__ для проверки, как и сказал предыдущий оратор вы создали еще один атрибут. Достаточно до присвоения и после вывести содержимое атрибутов объекта: до присвоения: __dict__ = {'_Auto__number': 'A777SD77'} после: __dict__ = {'_Auto__number': 'A777SD77', '__number': 'L123OX23'}

Комментариев нет:

Отправить комментарий