我尝试创建一个NamedTuple,其中一个字段默认为空字典。这主要起作用,但是默认值在NamedTuple的实例之间共享:
from typing import NamedTuple, Dict
class MyTuple(NamedTuple):
foo: int
bar: Dict[str, str] = {}
t1 = MyTuple(1, {})
t2 = MyTuple(2)
t3 = MyTuple(3)
t2.bar["test2"] = "t2"
t3.bar["test3"] = "t3"
print(t2) # MyTuple(foo=2, bar={'test2': 't2', 'test3': 't3'})
print(t3) # MyTuple(foo=3, bar={'test2': 't2', 'test3': 't3'})
assert "test3" not in t2.bar # raises
如何确保bar
字段是每个实例的新dict?PEP-526中的所有dict示例似乎都使用ClassVar,但这与我在这里想要的正好相反。你知道吗
我可以在这里使用带有default factory function(或attrs中的等效项)的数据类,但我目前需要支持python3.6.x和3.7.x,这样会增加一些开销。你知道吗
值得一提的是,我测试的python版本是3.7.3
typing.NamedTuple
/collections.namedtuple
不支持工厂函数,并且实现默认值的机制看起来不可能以任何合理的方式重载。也不能通过直接编写自己的__new__
来手动实现这样的默认值。你知道吗在aict中,唯一半合理的方法是编写一个
namedtuple
的子类,它实现自己的__new__
,以编程方式生成默认值:开销相对较小,但它确实涉及到六行样板文件。您可以将样板文件(以可能过于密集的代码为代价)从父级
MyTuple
的定义减少一行到最终MyTuple
的定义中,以减少冗长性,例如:但这仍然会形成继承层次结构,而不仅仅是
tuple
类的单个直接后代,就像从NamedTuple
继承一样。这不应该对性能产生有意义的影响,只是需要注意一些事情。你知道吗相关问题 更多 >
编程相关推荐