Правильный способ использования аксессуаров в 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. Преимущество свойств заключается в том, что вы можете использовать их для реализации функций, возвращающих или устанавливающих значения, которые извне класса кажутся просто доступными как обычные атрибуты участника.