我正在使用Python构建SQL仿真器并存储行,因此我想使用namedtuples,因为我可以轻松地通过select,order by和where来处理复杂的查询。我从普通元组开始,但是我经常发现自己在寻找行的属性并且需要维护列的顺序,所以我到达了namedtuple。
问题是我的某些列名带有下划线,导致我以ValueError: Field names cannot start with an underscore: '_col2'
我正在寻找一种使用带下划线的namedtuple(可能是某种替代类型)的方法,或者是一种合适的替代容器,该容器可以让我轻松地转换为原始列顺序的值元组,或者通过它们访问单个值字段名称。
我考虑过将一个领先的字符串附加到每个元组,然后编写一个中间件函数以用作getattr函数,但首先要删除该领先的字符串-但这似乎很骇人。
答案 0 :(得分:1)
您可以使用ValueError
参数避免rename=True
from collections import namedtuple
a = namedtuple("Table", "_col1 _col2 _col3 col4", rename=True)
print(a._fields)
('_ 0','_ 1','_ 2','col4')
@ Edit1 ,您可能想跟踪哪些字段已更改
from collections import namedtuple
columns = "_col1 _col2 _col3 col4"
a = namedtuple("Table", columns, rename=True)
old_feilds = columns.split()
new_feilds = a._fields
mapper = {}
for f1,f2 in zip(old_feilds, new_feilds):
mapper[f1] = f2
print(mapper)
{'_ col3':'_2','_col1':'_0','col4':'col4','_col2':'_1'}
答案 1 :(得分:0)
请考虑使用OrderedDict类型。 您可以通过方括号语法访问具有任何字符串名称的字段,并最终使用“ .items”将其转换为元组。
from collections import OrderedDict
ordered_form = OrderedDict([("col1", 'Apple'), ("col2", 'Orange'), ("_col3", 'Banana')])
ordered_form["_col3"] = 'Grapefruit'
tuple_form = tuple([i[1] for i in list(ordered_form.items())])
print(tuple_form)
答案 2 :(得分:0)
您始终可以使用type
:
obj = type('Foo', tuple(), {'_closed': False})()
现在我可以访问它:
obj._closed
我们添加一些实用程序功能:
from collections import deque
from itertools import islice
it_consumes = (lambda it, n=None: deque(it, maxlen=0) or None if n is None
else next(islice(it, n, n), None))
def update_d(d, **kwargs):
d.update(kwargs)
return d
好的,现在让我们以tuple
中的任意t = 'a', 'b', 'c', '_can'
为例:
MyClass = type('MyClass', tuple(),
update_d({k : None for k in t},
__init__=lambda self, **kwargs: it_consumes(
setattr(self, k, v)
for k,v in kwargs.items())))
然后可以这样使用:
obj = MyClass(a=5, b=6, _can='haz')
print('obj._can:', obj._can)