Как заставить атрибут экземпляра всегда быть списком? - PullRequest
0 голосов
/ 22 мая 2019

У меня есть класс, который содержит много атрибутов. Есть атрибут, которым я всегда хочу быть list, то есть он не может быть перезаписан чем-то еще, и он всегда будет вести себя как list.

class SomeClass(object):
    def __init__(self):
        self.var1 = None
        self.var2 = None
        self.alwaysList = []

sc = SomeClass()
sc.alwaysList.append("Something") # Valid
sc.alwaysList = 5 # Should be invalid

Должен ли я писать функции-оболочки? Должен ли я использовать @property?

1 Ответ

4 голосов
/ 22 мая 2019

Вы можете использовать @property и @alwaysList.setter, чтобы определить поведение при установке пропеллера.Вы можете строго применять тип списка в установщике (или проверить абстрактный базовый класс: isinstance(newVal, collections.Sequence)), или (возможно, более питонический) взять все, что можно повторить, и преобразовать в список:

class SomeClass(object):
    def __init__(self):
        self.var1 = None
        self.var2 = None
        self._alwaysList = []

    @property
    def alwaysList(self):
        return self._alwaysList

    @alwaysList.setter
    def alwaysList(self, newVal):
        ''' a little more forgiving of input '''
        try:
            self._alwaysList = list(newVal)

        except TypeError:
            # print warning or raise
            print("alwaysList must be iterable: {} is not iterable".format(newVal))



sc = SomeClass()
sc.alwaysList.append("Something") # Valid
sc.alwaysList = 90                # error alwaysList must be iterable: 90 is not iterable
sc.alwaysList = "somthing"        # string is iterable -- convert to list
sc.alwaysList                     # ['s', 'o', 'm', 't', 'h', 'i', 'n', 'g']

Использование вышеявляется более гибким - вы можете передавать все, что можно итеративно, например sc.alwaysList = range(10), при этом всегда сохраняя список в свойстве.

...