使用属性子类化 namedtuple

Subclassing namedtuple with properties

我有一些 类 已经定义了属性,我现在正在寻找一种将数据打包到命名元组中以与数据库交互的方法。我想将一些属性(但不是全部)放入命名元组中,以便我可以在从数据库中检索数据时分配字段名称。

from collections import namedtuple
import sqlite3

Foo = namedtuple('Foo', 'a, b')

class FooChild(Foo):

    def do_some_calculation(self):
        self.d = 2
        return self.d

    @property
    def b(self):
        return (self.a,)*2 + (self.d,)

    @property
    def c(self):
         return 'bar'

def retrieve_data():
    conn = sqlite3.connect('/foodata')
    cursor = conn.cursor()
    cursor.execute('SELECT a, b FROM foos')
    for foo in map(Foo._make, cursor.fetchall()):
        print(foo.a, foo.b)


foo = Foo(11, ())
print(foo.a, foo.b, foo._asdict())

但是 print(foo._asdict()) returns OrderedDict([('a', 11), ('b', ())]) 因为命名的元组是不可变的。

'b' 属性 在 namedtuple 的实例化过程中无法计算。

在这种情况下,有人可以建议怎么走吗?

是的,这是错误的做法。我知道使用它来编写非常短的代码很诱人,但它只会搞乱其他事情。保持简单,以便所有读者(包括未来的您)都清楚地知道发生了什么。

class FooV2(object):
    def __init__(self, a, b):
        self.a = a
        self.b = b

    # c and d and stuff

def retrieve_data():
    conn = sqlite3.connect('/foodata')
    cursor = conn.cursor()
    cursor.execute('SELECT a, b FROM foos')
    for row in cursor.fetchall():
        foo = FooV2(*row)
        print(foo.a, foo.b)