[英]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__.cols
和self.__class__.table
替换对self.cols
和self.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 时,您应该填写每一列。
这就是为什么您需要两个列表具有相同长度的原因。 否则你可能没有所有的属性。
它的完成方式是使用列名称设置属性,这不是最佳选择,因为如果您有一个名为cols
或table
甚至__repr__
的列,它可能会破坏您的代码。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.