![](/img/trans.png)
[英]How can I reference the __init__ method of a derived class in Python from the base class?
[英]How to set the "base class list" in derived class __init__ in Python?
我有一个扩展列表的 class; 尽可能简化,它看起来像:
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 的情况,我应该然后说super().__init__([...])
创建新的“空”列表的两个副本:一个作为参数给 super.init 和由该 function 创建的副本?
另外,我的代码是否用于创建现有grid
实例的副本,特别是self__dict__ |= data.__dict__.copy()
,是通往 go 的方式? 实际上,除了.score
之外,还有更多属性,其中一些是列表。 我知道我必须(?)为它们中的每一个使用单独的copy()
来有效地创建这些的新副本,而不仅仅是对旧实例的属性的引用。 我应该使用一些deepcopy
模块以“更清洁”(?)的方式做到这一点吗?
忽略其他一些问题,我会这样写 class :
class grid(list):
def __init__(self, lists: list[list]):
self.extend([x] for x in lists)
@classmethod
def from_grid(cls, g: grid):
# A grid is already a list of lists
return cls(g)
@classmethod
def from_int(cls, n):
return cls([[] for _ in range(n)])
像list([1,2,3])
这样的调用首先使用list.__new__
创建一个空列表(忽略参数,尽管可能使用它为新列表预分配足够的空间以容纳三个值),然后传递新的list 和给定的 iterable 到list.__init__
将值从 iterable 复制到新列表中。 您可以通过覆盖__init__
来检查self
在调用super().__init__
之前和之后的值来看到这一点:
class A(list):
def __init__(self, x):
print(self)
super().__init__(x)
print(self)
然后
>>> a = A([1,2,3])
[]
[1, 2, 3]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.