繁体   English   中英

如何在 Python 中的派生 class __init__ 中设置“基础 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.

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