【发布时间】:2026-02-06 11:05:02
【问题描述】:
我有一个扩展列表的类;尽可能简化,看起来像:
class grid(list):
def __init__(self, data):
"If data is an int, create empty grid of size data; if data is a list, initialize grid with that data."
if type(data) == grid: # make a new copy of the old grid instance 'data'
self += data
self.__dict__ |= data.__dict__.copy()
elif type(data) == list:
self += data
self.score = sum(len(row) for row in data)
elif type(data) == int:
self += [[] for _ in range(data)] # NOTE: [[]]*data creates multiple references to the same empty row!
self.score = 0
else: raise Exception("data must be integer or list!")
它有效,但我觉得很尴尬,我必须(?)使用+= 将我想要创建的内容“附加”到最初为空的“基本列表”:
如果使用,例如self = data,那么self 将成为一个基本列表,并且设置像“self.score = ...”这样的属性会导致错误。
我认为和/或知道我也可以使用super().__init__(data) 将给定的初始数据复制到基础列表中。但它看起来有点矫枉过正,不必要地“沉重”。 (我的做法不是(很多)更有效率吗?毕竟空列表已经存在,super().__init__ 不会创建一个全新的列表吗?)对于 data=int 的情况,我应该说@ 987654327@ 创建 两个 新“空”列表的副本:作为参数提供给 super.init 的副本和由该函数创建的副本!?
另外,我用于创建grid 的现有实例的副本的代码,尤其是self__dict__ |= data.__dict__.copy(),是否可行?实际上,除了.score,还有更多的属性,其中一些是列表。我知道我必须(?)为每个人使用单独的copy()s 来有效地创建这些副本的新副本,而不仅仅是引用旧实例的属性。我应该使用一些deepcopy 模块以“更清洁”(?)的方式做到这一点吗?
编辑/更新:澄清一下,我的问题是是否有办法分配一个值到基本列表(在本例中,或在一般情况下为基本),如我们将值分配给对象的其他组件(即属性)(例如,self.__inner_list = list(data).)。 “行”(列表的元素)的类型无关紧要,为了简单起见,我在空网格中使用了 [] 但实际上行是我真实代码中的集合,但我也允许列表和字典 - 特别是因为我必须/want/do 使用空集的常用数学符号“{}”(但在 Python 中表示空的 dict)输出空行,并且为了保持一致性,还希望允许将其作为输入。从 cmets 看来,似乎没有这种方法可以“简单地”为基础对象分配一个值(毕竟这是合乎逻辑的)。
【问题讨论】:
-
我不确定我是否会为此使用继承。虽然列表列表可用于表示一个网格,但真的所有列表列表都是网格吗?我可能会 1) 定义一个包含列表列表的类。 2) 让
__init__将列表列表作为参数 3) 定义单独的类方法,这些方法将现有网格或 int 作为参数以返回新网格。 4) 定义对网格有意义的方法,而不是仅仅假设所有list方法都是有效的。 (例如,你真的要允许g = grid(3); g.append("foo")吗?) -
__init__不会创建列表;它初始化它。list.__new__调用type.__new__来实际创建新列表,该列表被传递给list.__init__以将给定迭代中的值添加到其中。 -
不,我的问题是,你认为
[[1], [2,3,4,5], [6,7]]是一个网格吗?当参数是整数时,您已经在创建一个空列表列表;我只是将它转移到一个单独的方法中,以避免使__init__复杂化,您希望它尽可能简单。 (理想情况下,初始化网格有一种“规范”方式,所有其他方式都可以按照规范方式实现;以我的回答为例。) -
使用
super().__init__不会影响性能。这只是对内置方法的另一个调用,就像self += ...是对self = self.__iadd__(...)的调用一样。 -
我不确切知道 如何
list.__init__工作,只是它做的一件事是复制任何可迭代的作为参数到新列表中。
标签: python oop inheritance