繁体   English   中英

Python - class object 在 ZC1C425268E68385D1AB5074C17A94F1Z 内初始化

[英]Python - class object initialization within function

下面的代码有效(它最终将通过 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”的长度相同? 有人会解释这种行为吗?

当您实例化由build_row() function 返回的 class 时, data会被赋予一个值。

保证与self.cols的长度相同; 也许您从未实例化 class,因此永远不会看到错误。

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

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

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

DataRow.cols = cols.split()

早在任何实例被创建之前——这就是这个断言有效的原因。

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

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

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

它的完成方式是使用列名称设置属性,这不是最佳选择,因为如果您有一个名为colstable甚至__repr__的列,它可能会破坏您的代码。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM