Typing.NamedTuple和可变默认参数
鉴于我想正确使用类型注释来命名来自打字模块的元组:
from typing import NamedTuple, List
class Foo(NamedTuple):
my_list: List[int] = []
foo1 = Foo()
foo1.my_list.append(42)
foo2 = Foo()
print(foo2.my_list) # prints [42]
避免 Python 中可变默认值痛苦的最佳或最干净的方法是什么?我有一些想法,但似乎没有什么是好的
-
None默认使用class Foo(NamedTuple): my_list: Optional[List[int]] = None foo1 = Foo() if foo1.my_list is None foo1 = foo1._replace(my_list=[]) # super ugly foo1.my_list.append(42) -
覆盖
__new__或__init__不起作用:AttributeError: Cannot overwrite NamedTuple attribute __init__ AttributeError: Cannot overwrite NamedTuple attribute __new__ -
特别的
@classmethodclass Foo(NamedTuple): my_list: List[int] = [] @classmethod def use_me_instead(cls, my_list=None): if not my_list: my_list = [] return cls(my_list) foo1 = Foo.use_me_instead() foo1.my_list.append(42) # works! -
也许
frozenset完全使用和避免可变属性?但这不适用于Dicts,因为没有frozendicts。
有人有好的答案吗?
回答
使用数据类而不是命名元组。数据类允许字段指定默认工厂而不是单个默认值。
from dataclasses import dataclass, field
@dataclass(frozen=True)
class Foo:
my_list: List[int] = field(default_factory=list)