python - _replace 不调用命名元组子类的 __new__

标签 python python-3.x namedtuple

我有一个命名元组类型的子类:

class User(namedtuple('User', ['first_name'])):
    __slots__ = ()

    def __new__(cls, *args, **kwargs):
        result = super().__new__(cls, *args, **kwargs)
        if not result.first_name:
            raise InvalidUserError({InvalidUserError.EMPTY_FIRST_NAME})
        return result

创建新用户按预期工作:

>>> try: User(first_name='')
... except Exception as e: print(type(e))
<class 'InvalidUserError'>

但是,当使用 _replace 时,不会调用 __new__ 方法:

>>> User(first_name='foo')._replace(first_name='')
User(first_name='')

有没有办法保证namedtuple的不变量?我使用的是 Python 3.4。

最佳答案

Python 通常依赖于约定和良好的文档,而不是强烈执行的不变量。即使没有 _replace(),您也可以绕过 User.__new__():

>>> class X(tuple): __slots__ = ()
>>> x = C(('',))
>>> x.__class__ = User
>>> x
User(first_name='')

所以不,你永远无法严格执行这一点。只需避免使用 _replace(),或使用调用 User.__new__() 的版本覆盖它,或检查不同级别的不变量即可。

_replace() 的示例实现:

def _replace(self, **kwargs):
    return type(self)(**dict(vars(self), **kwargs))

关于python - _replace 不调用命名元组子类的 __new__,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25741810/

相关文章:

Python 字节数组打印

python - 如何在python中分别计算每个簇的Silhouette Score

python-3.x - 如何使用 webdriver 的热键加载扩展?

python - 将数据存储到具有空字段的命名元组中以添加其他内容

Python:从namedtuple列表中获取参数值列表

python - "hybrid models"的模型记录(例如 SKlearn Pipeline 包括 KerasWrapper)可能吗?

python - 即使页面存在,为什么我在 python 请求中收到 404 错误?

Python 数据类 : What type to use if __post_init__ performs type conversion?

命名元组的 Python 列表,替换属性

python - 列表的排列