Python объект как тип свойства - PullRequest
0 голосов
/ 06 июня 2019

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

Класс, над которым я работаю, должен представлять какой-то (сеть)диммер.Можно запросить / отправить «ресурсы», адресованные определенным идентификатором, для управления устройством.Я хотел бы представить эти «ресурсы» как свойства моего класса, скрывающие механизм запроса / отправки и зашифрованные идентификационные номера.Некоторые из этих «ресурсов» являются просто примитивными типами (int, float, ...), но некоторые являются более сложными, поэтому я просто создал для них простые классы.Это прекрасно работает, но есть ужасный источник ошибки: невозможно напрямую изменить атрибут этого свойства, я должен установить свойство полностью каждый раз.

DUMMY_DB = {0x0001: bytearray([0x00])}


class State:
    def __init__(self, on, value):
        self.on = on
        self.value = value

    @staticmethod
    def from_int(val):
        return State(bool(val & 0x80), val & 0x7f)

    def __int__(self):
        return self.on << 7 | self.value


class Dimmer:
    @property
    def state(self) -> State:
        return State.from_int(self._request(0x0001)[0])  # ID 0x0001 => State

    @state.setter
    def state(self, val: State):
        self._send(0x0001, [int(val)])  # ID 0x0001 => State

    # several more properties...

    def _request(self, ident) -> bytearray:
        # usually get resource 'ident' from network/file/...
        return DUMMY_DB[ident]

    def _send(self, ident, value):
        # usually set resource 'ident' on network/file/... using value
        DUMMY_DB[ident] = value


if __name__ == '__main__':
    dimmer = Dimmer()
    print(dimmer.state.on, dimmer.state.value)  # start state
    dimmer.state.on = True
    dimmer.state.value = 15
    print(dimmer.state.on, dimmer.state.value)  # state did not change
    dimmer.state = State(True, 15)
    print(dimmer.state.on, dimmer.state.value)  # state changed

Первая печать простопоказать начальное состояние («Ложь 0»).Но вторая печать показывает, что

dimmer.state.on = True
dimmer.state.value = 15

бесполезны.Это потому, что dimmer.state возвращает новый изменяемый объект, который изменяется и уничтожается без дальнейшего использования.Только после полного присваивания свойства вызывается метод установки и вызывается Dimmer._send.

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...