如何使用@property 装饰器来限制列表中的值

Posted

技术标签:

【中文标题】如何使用@property 装饰器来限制列表中的值【英文标题】:How to use @property decorator to restrict values inside a list 【发布时间】:2020-09-23 07:23:16 【问题描述】:

我是python的新手。所以如果我写错了,请随时纠正。

我创建了一个新类 ClassA,它有一个属性 modified,它是一个列表。

这个类最初看起来像这样:

class ClassA:
        def __init__(self):
            self.modified = []

我希望在此列表中添加(或修改)的元素首先通过检查。例如。我只想要此列表中的日期,其格式为YYYY-MM-DD。所以我认为@propoerty装饰器可以做一些工作。我是这样使用的:

class ClassA:

        def __init__(self):
            self._modified = []

        @property
        def modified(self):
            return getattr(self, "_modified")

        @modified.setter
        def modified(self, value):
            if not isinstance(value, list):
                raise TypeError("value passed must be a list")
            else:
                modified_list = []
                for item in value:
                    if isinstance(item, str):
                        result = performValidationCheck(item)
                        if not result:
                            raise ValueError("date format incorrect")
                        else:
                            modified_list.append(date.getDateAsString())
                    else:
                        raise TypeError("%s must be of type string")
                self._modified = modified_list

        def add_modified_date(self, date):
            if not isinstance(date, str):
                raise TypeError("date passed must be a string")
            result = performValidationCheck(date)
            if not result:
                raise ValueError(libsbml.OperationReturnValue_toString(result))
            self._modified.append(date)

但是,我仍然可以使用classA.modified[index] 更改modified 列表中条目的值。甚至 append 函数也在这个列表上工作。

我已经实现了performValidationCheck() 函数,这里不关心这个。

有人可以帮我解决这个问题吗?

【问题讨论】:

【参考方案1】:

但是,我仍然可以使用 classA.modified[index] 更改已修改列表中条目的值。甚至附加函数也在这个列表上工作。但是,我仍然可以使用 classA.modified[index] 来更改修改后列表中条目的值。甚至 append 函数也在这个列表上工作。

当然。 @property 仅控制获取/设置对象的属性。如果在属性上设置的对象是可变的,它就不能做任何事情。

有人可以帮我解决这个问题吗?

要么使用一个自定义的类似列表的集合(一个 MutableSequence)来动态验证它的值,要么使用一个 tuple(基本上是一个不可变的列表),这样调用者将无法就地修改它。

【讨论】:

“要么使用自定义的类似列表的集合(一个 MutableSequence),它可以即时验证其值”,您的意思是从列表派生的类? 不,派生内置函数是有风险的,因为不能保证他们会回调任何东西,所以很难保证他们正在做你想做的事情,例如list.extend 可能不会在内部调用 list.append。然而,抽象基类可以用作需要一堆抽象方法的“模板”,并提供许多其他方法,所以如果你从collections.abc.MutableSequence派生,你只需要实现5个方法(@987654325 @、__setitem____delitem____len__insert),它会自动生成十几个其他对象来提供一个非常类似于列表的对象。

以上是关于如何使用@property 装饰器来限制列表中的值的主要内容,如果未能解决你的问题,请参考以下文章

Python3通过装饰器来创建property

如何通过自定义装饰器记录@Input@Output值的值。

python基础语法15 组合,封装,访问限制机制,内置装饰器property

如何使用装饰器来修改 *args 的类型?

如何在 Python 中使用类装饰器来混合行为?

你如何使用 Flask-Login 和自定义 Python 装饰器来分配用户权限?