Ответ 1
def attrsetter(attr):
def set_any(self, value):
setattr(self, attr, value)
return set_any
a = property(fset=attrsetter('_a'))
b = property(fset=attrsetter('_b'))
c = property(fset=attrsetter('_c'))
Рассмотрим следующие определения классов
class of2010(object):
def __init__(self):
self._a = 1
self._b = 2
self._c = 3
def set_a(self,value):
print('setting a...')
self._a = value
def set_b(self,value):
print('setting b...')
self._b = value
def set_c(self,value):
print('setting c...')
self._c = value
a = property(fset=self.set_a)
b = property(fset=self.set_b)
c = property(fset=self.set_c)
Обратите внимание, что set_[a|b|c]()
делает то же самое. есть ли способ определить:
def set_magic(self,value):
print('setting <???>...')
self._??? = value
один раз и используйте его для a, b, c следующим образом
a = property(fset=self.set_magic)
b = property(fset=self.set_magic)
c = property(fset=self.set_magic)
def attrsetter(attr):
def set_any(self, value):
setattr(self, attr, value)
return set_any
a = property(fset=attrsetter('_a'))
b = property(fset=attrsetter('_b'))
c = property(fset=attrsetter('_c'))
Я вижу, что ваши сеттеры просто регистрируют сообщение, а затем просто присваивают значение - на самом деле ваш принятый ответ просто присваивает значение. Используете ли вы этот шаблон, потому что это принятая практика/обычная мудрость на каком-то другом языке, возможно, имя, начинающееся с буквы "J"? Если да, то, пожалуйста, узнайте, что подход Pythonic к этому же дизайну намного проще:
class Of2010(object):
def __init__(self):
self.a = 1
self.b = 2
self.c = 3
Нет никаких настроек, никаких промежуточных вызовов функций просто для назначения значения. "Что ты говоришь?" Публичное воздействие переменных-членов?!!" Ну, да, на самом деле.
Посмотрите на эти классы с точки зрения клиентского кода. Чтобы использовать свой класс, клиенты создают объект, а затем присваивают свойство "a" , используя:
obj = Of2010()
obj.a = 42
Примечательно, что это тот же самый код для 5-линейного класса I, опубликованного выше.
Почему J-язык поощряет более верный стиль собственности? Сохранение интерфейса класса в случае будущих изменений требований. Если в какой-то момент времени некоторое другое значение объекта должно измениться вместе с любыми изменениями в a, тогда вы должны реализовать механизм свойств. К сожалению, J-язык раскрывает характер механизма доступа атрибутов к клиентскому коду, так что введение свойства в какой-то момент в будущем представляет собой навязчивую задачу рефакторинга, которая потребует перестройки всех клиентов, которые используют этот класс и его атрибут "a" .
В Python это не так. Доступ к атрибуту "a" объекта определяется во время выполнения в вызывающем. Поскольку прямой доступ и доступ к свойствам "выглядят" одинаково, ваш класс Python сохраняет этот интерфейс, даже если фактический механизм отличается. Важно то, что он идентичен в отношении кода клиента.
Итак, в Java, эта сложность свойств вводится с самого начала этого класса (и фактически, Accepted Practice, из всех классов), вне всякого сомнения, что это может понадобиться в будущем. С Python можно начать с реализации Simplest Thing, которая могла бы работать, т.е. Прямого доступа к простым переменным-членам, оставляя сложный подход на время в будущем, что дополнительный материал действительно необходим и имеет ценность. Поскольку этот день, возможно, никогда не наступит, это огромный шаг вперед в получении этой первой рабочей версии вашего кода в дверь.
class...
def __setattr__(self, name, value):
print 'setting', name
self.__dict__[name] = value
Что это.
Возможно, вы ищете
__setattr__(self, name, value)
Посмотрите здесь