不可变列表属性

时间:2018-05-14 14:27:15

标签: python

如何创建始终包含相同列表的类属性?它应该始终引用相同的列表,尽管可以更改列表的内容。

显而易见的解决方案是使用属性。

class Table(list):
    def filter(kwargs):
    """Filter code goes here."""


class db:
    _table = Table([1, 2])
    table = property(lambda self: self._table)


db.table.append(3)

我原以为db.table应该返回一个列表,你应该能够追加到这个列表。但不,这段代码抛出异常:

AttributeError: 'property' object has no attribute 'append'

如何创建始终引用同一列表的属性?

插图:

db.table = [x for x in db.table if x > 2]
db.filter(3)    # This filter method got lost when reassigning the table in the previous line.

3 个答案:

答案 0 :(得分:2)

这是一个使用class属性的解决方案,使用此答案:How to make a class property?

class ClassPropertyDescriptor(object):

    def __init__(self, fget, fset=None):
        self.fget = fget
        self.fset = fset

    def __get__(self, obj, klass=None):
        if klass is None:
            klass = type(obj)
        return self.fget.__get__(obj, klass)()

    def __set__(self, obj, value):
        if not self.fset:
            raise AttributeError("can't set attribute")
        type_ = type(obj)
        return self.fset.__get__(obj, type_)(value)

    def setter(self, func):
        if not isinstance(func, (classmethod, staticmethod)):
            func = classmethod(func)
        self.fset = func
        return self

def classproperty(func):
    if not isinstance(func, (classmethod, staticmethod)):
        func = classmethod(func)

    return ClassPropertyDescriptor(func)


class db(object):
        _table = [1,2]

        @classproperty
        def table(cls):
                return list(cls._table)



t = db.table
t.append(3)
print t  # [1, 2, 3]
print db.table  # [1, 2]

答案 1 :(得分:0)

没有可以添加的不可变的功能。 Hoewever我会建议创建一个存储列表的类。并使列表不可变定义只有setter并使列表私有。并且为了更改列表元素,您可以创建方法。

你会有像

这样的东西

类FinalList:

列表

<强>初始化(列表)

的GetList()

追加(元素)

删除(元件)

...等

答案 2 :(得分:0)

为了比较,这里是作为类的实例编写的代码。

class Table(list):
    def filter(kwargs):
        """Filter code goes here."""


class DB:
    def __init__(self):
        DB._table = Table([1, 2])

    table = property(lambda self: DB._table)


db = DB()

db.table.append(3)
print(db.table)
db.table = [2]

输出:

[1, 2, 3]
AttributeError: can't set attribute

完美。这比创建类属性简单得多。

从技术上讲,我们使用的是一个类实例,它使代码变得更加简单。但是,通过将Table存储在类本身中,我们确保所有实例共享相同的表。