Правильный способ использования аксессуаров в Python?

Как вы определяете класс "Автомобиль" с атрибутом "Скорость" в Python? Мой фон находится в Java, и кажется, что в Python не используются методы get/set.

class Car(object):
    def __init__(self):
        self._speed = 100

    @property
    def speed(self):
        return self._speed

    @speed.setter
    def speed(self, value):
        self._speed = value

Ответ 1

В Python мы вообще избегаем геттеров и сеттеров. Просто используйте атрибут .speed:

class Car(object):
    speed = 0

    def __init__(self):
        self.speed = 100

См. Python - это не Java для мотиваций и больше ошибок, чтобы избежать:

В Java вы должны использовать геттеры и сеттеры, потому что использование открытых полей не дает вам возможности вернуться назад и передумать позже, используя геттеры и сеттеры. Таким образом, на Java вы также можете избавиться от проблемы. В Python это глупо, потому что вы можете начать с нормального атрибута и изменить свое мнение в любое время, не затрагивая никаких клиентов класса. Итак, не пишите геттеры и сеттеры.

Используйте property, когда вам действительно нужно выполнять код при получении, настройке или удалении атрибута. Валидация, кеширование, побочные эффекты и т.д. - все это справедливые варианты использования свойств. Просто не используйте их до тех пор, пока это не будет необходимо.

Ответ 2

Я бы использовал атрибуты, например:

class Car(object):
    def __init__(self):
        self.speed = 100

где вы можете изменить и получить его точно так же. Обозначение @property, вероятно, более полезно для обертывания классов, использующих методы get/set Java/C, виртуальные атрибуты или если вам нужно манипулировать введенными значениями.

Я часто использую это в классах графического интерфейса, где я могу легко принудительно перерисовать экран на основе изменения атрибутов виджетов, типа пользовательской системы событий.

Ответ 3

Поскольку технические атрибуты никогда не являются частными в Python, методы get/set не считаются "pythonic". Это стандартный способ доступа к атрибутам объекта:

class MyClass():
    def __init__(self):
        self.my_attr = 3

obj1 = MyClass()
print obj1.my_attr #will print 3
obj1.my_attr = 7
print obj1.my_attr #will print 7

Вы можете, конечно, использовать геттеры и сеттеры, и вы можете несколько эмулировать частных членов, добавив __ к вашим атрибутам:

class MyClass():
    def __init__(self):
        self.__my_attr = 3
    def set_my_attr(self,val):
        self.__my_attr = val
    def get_my_attr(self):
        return self.__my_attr

obj1 = MyClass()
print obj1.get_my_attr() #will print 3
obj1.set_my_attr(7)
print obj1.get_my_attr() #will print 7

__ "управляет" именем переменной: извне какой-то класс classname, в котором определен __attr, __attr переименован как _classname__attr; в приведенном выше примере вместо использования геттеров и сеттеров мы могли бы просто использовать obj1._MyClass__my_attr. Таким образом, __ препятствует внешнему использованию атрибутов, но не запрещает его так же, как это делает модификатор Java private.

Есть также, как вы упомянули в своем вопросе, свойства, доступные в Python. Преимущество свойств заключается в том, что вы можете использовать их для реализации функций, возвращающих или устанавливающих значения, которые извне класса кажутся просто доступными как обычные атрибуты участника.