如何强制实例属性始终为列表?

时间:2019-05-22 16:38:40

标签: python list properties wrapper

我有一个包含许多属性的类。我希望有一个属性始终是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 个答案:

答案 0 :(得分:4)

可以在设置道具时使用@property@alwaysList.setter定义行为。您可以在setter中严格执行列表类型(或测试抽象基类:isinstance(newVal, collections.Sequence)),或(也许更Python化)采用所有可迭代的内容并转换为列表:

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)之类的可迭代对象,同时始终在属性中保留一个列表。