首页 > 解决方案 > 如何强制实例属性始终是列表?

问题描述

我有一个包含许多属性的类。有一个属性我想永远是 a list,那就是它不能被其他任何东西覆盖,它的行为总是像 a 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吗?

标签: pythonlistpropertieswrapper

解决方案


您可以使用@propertyand@alwaysList.setter来定义设置 prop 时的行为。您可以在 setter 中严格强制执行列表类型(或测试抽象基类isinstance(newVal, collections.Sequence):),或者(可能更 Pythonic)采用任何可迭代的内容并转换为列表:

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)同时仍然在属性中保留一个列表。


推荐阅读