Python - 函数内的类对象初始化

时间:2011-06-13 03:23:42

标签: python initialization python-3.x

下面的代码有效(它最终将通过SQL从数据库中提取记录),但我无法理解为什么下面代码中的assert语句有效。

def build_row(table, cols):
    """Build a class that creates instances of specific rows"""
    class DataRow:
        """Generic data row class, specialized by surrounding function"""
        def __init__(self, data):
            """Uses data and column names to inject attributes"""
            assert len(data)==len(self.cols)
            for colname, dat in zip(self.cols, data):
                setattr(self, colname, dat)
        def __repr__(self):
            return "{0}_record({1})".format(self.table, ", ".join(["{0!r}".format(getattr(self, c)) for c in self.cols]))
    DataRow.table = table
    DataRow.cols = cols.split()
    return DataRow

确定'数据'的长度是多少?如何保证与'self.cols'的长度相同?有人请解释一下这种行为吗?

3 个答案:

答案 0 :(得分:1)

在实例化data函数返回的类时,

build_row()会得到一个值。

保证与self.cols的长度相同;也许你永远不会实例化这个类,所以永远不会看到错误。

答案 1 :(得分:1)

如果您将self.colsself.table的引用替换为self.__class__.colsself.__class__.table,这可能对您更有意义。这种混淆是由于通过self对象访问类属性就好像它们是实例属性一样,以及为什么我不特别喜欢这种编码习惯。在查看__init__中的代码时,实例属性通常会分配给它们的值,因此立即看到读取 self.cols的值的语句很不稳定 - 其中哎呀self.cols初始化了吗?!另一方面,如果您将此断言更改为:

assert len(data)==len(self.__class__.cols)

然后更清楚的是,数据值列表应该与此DataRow实例的已定义列列表的长度相同。类属性cols在类定义之后立即初始化,在此语句中:

DataRow.cols = cols.split()

在任何实例创建之前很久 - 这就是这个断言有效的原因。

此代码的编写者可能会考虑转换为更新的namedtuple构造。

答案 2 :(得分:0)

定义DataRow时,列名称将在变量self.cols中设置。因此,当您实例化该类时,您应该填充每一列。

这就是为什么你需要两个长度相同的列表。否则你可能没有所有的属性。

它的完成方式是设置一个属性,其中列的名称不是最佳选项,因为如果您有一个名为colstable或甚至{{1}的列},它可能会破坏你的代码。