我尝试将以下功能添加到Python collections.namedtuple
Lazy = namedtupleforthelazytm('Lazy', ('A', 'B'))
inst = Lazy(1, 2)
# namedtuple has this:
inst[0]
inst.A
# I want this:
SV = 'A'
inst[SV]
以下代码似乎只能实现
import collections
def namedtupleforthelazytm(classname, fieldnames):
class lazy(collections.namedtuple(classname + '_wrapped', fieldnames)):
__slots__ = ()
def __getitem__(self, key):
if key in self._fields:
return super().__getattribute__(key)
return super().__getitem__(key)
lazy.__name__ = classname
return lazy
然而,所造成的性能损失非常严重:
>>> from timeit import timeit
>>> from collections import namedtuple
>>> from nmdtpl import namedtupleforthelazytm
>>>
>>> def stress(o):
... for i in range(100000):
... x = o[0]
... x = o[1]
... x = o.a
... x = o.b
...
>>> orig = namedtuple('O', ('a', 'b'))(1, 2)
>>> subc = namedtupleforthelazytm('S', ('a', 'b'))(1, 2)
>>>
>>> timeit('f(a)', number=10, globals={'f':stress, 'a':orig})
0.13294775993563235
>>> timeit('f(a)', number=10, globals={'f':stress, 'a':subc})
2.1330132230650634
我的问题是:有没有办法让所需功能更便宜(不一定从namedtuple
开始)?
澄清:
namedtuple
给我的美妙之处在于,与使用元组相比,它使代码更具可读性,同时避免了完整映射的成本。
我可以使用getattr(inst, SV)
,但这样做会破坏目的(可读性) - 如果你发现一个单一的太易于阅读以保证任何行动,那就认为是嵌套结构。