在命名元组中使用下划线

时间:2019-01-25 18:38:29

标签: python namedtuple

我正在使用Python构建SQL仿真器并存储行,因此我想使用namedtuples,因为我可以轻松地通过select,order by和where来处理复杂的查询。我从普通元组开始,但是我经常发现自己在寻找行的属性并且需要维护列的顺序,所以我到达了namedtuple。

问题是我的某些列名带有下划线,导致我以ValueError: Field names cannot start with an underscore: '_col2'

结尾

我正在寻找一种使用带下划线的namedtuple(可能是某种替代类型)的方法,或者是一种合适的替代容器,该容器可以让我轻松地转换为原始列顺序的值元组,或者通过它们访问单个值字段名称。

我考虑过将一个领先的字符串附加到每个元组,然后编写一个中间件函数以用作getattr函数,但首先要删除该领先的字符串-但这似乎很骇人。

3 个答案:

答案 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)