Повторяющиеся декораторы для переменных экземпляра - PullRequest
1 голос
/ 28 марта 2020

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

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

class Variable():

    __type = 'Variable'

    def __init__(self, id = None, updateable = True, name = 'Variable', value=None):
        if id is not None:
            self.id = id
        if value is not None:
            self.value = value
        self.updateable = updateable
        self.name = name

    @property
    def id(self):
        return self.__id

    @id.setter
    def id(self, id=None):
        if isinstance(id, int):
            self.__id = id
        else:
            raise Exception('"id" must be an integer ')

    @property
    def updateable(self):
        return self.__updateable

    @updateable.setter
    def updateable(self, updateable=None):
        if isinstance(updateable, bool):
            self.__updateable = updateable
        else:
            raise Exception('"updateatable" must be a bool')

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name=None):
        if isinstance(name, str):
            self.__name = name
        else:
            raise Exception('"name" must be a string')

    @property
    def value(self):
        return self.__value

    @value.setter
    def value(self, value=None):
        if isinstance(value, np.ndarray):
            self.__value = value
        else:
            raise Exception('"value" not an instance of np.ndarray')

1 Ответ

1 голос
/ 28 марта 2020

Книга Python Кулинарная книга, 3-е издание от Jones & Beazley содержит рецепт 9.21 Как избежать повторяющихся методов свойств , который делает почти точно то, что вам нужно - я Настоятельно рекомендуем получить копию книги (или электронной книги) всем, кто заинтересован в том, чтобы стать опытным Python программистом, как можно быстрее, так как в нем много подобных драгоценных камней. (Отказ от ответственности: я не имею никакого отношения к издателю или авторам.)

Почти все в Python является первоклассным объектом, поэтому можно создать функцию, которая просто определяет свойство и возвращает его. Подобные действия позволят вам следовать принципу DRY (и писать менее скучный избыточный код).

def typed_property(name, expected_type):
    storage_name = '__' + name

    @property
    def prop(self):
        return getattr(self, storage_name)

    @prop.setter
    def prop(self, value):
        if not isinstance(value, expected_type):
            type_name = expected_type.__name__
            raise TypeError('"{}" must be a {}'.format(name, type_name))
        setattr(self, storage_name, value)

    return prop


class Variable():
    __type = 'Variable'

    id = typed_property('id', int)
    updateable = typed_property('updateable', bool)
    name = typed_property('name', str)
    value = typed_property('value', np.ndarray)

    def __init__(self, id=None, updateable=True, name='Variable', value=None):
        if id is not None:
            self.id = id
        if value is not None:
            self.value = value
        self.updateable = updateable
        self.name = name
...