我有一个名为元组类型的子类:
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。
答案 0 :(得分:2)
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))