【问题标题】:Create a subclass of list without deep copy创建没有深拷贝的列表子类
【发布时间】:2017-02-05 10:21:20
【问题描述】:

我想继承list 以添加一些功能,例如my_func

在创建MyList 对象并让MyList 引用与用于构造它的列表相同的列表时,有没有办法在不复制整个列表的情况下执行此操作,即进行浅拷贝?

class MyList(list):
    def my_func(self):
        # do some stuff
        return self


l1 = list(range(10))
l2 = MyList(l1)

print(l1)
print(l2)

l1[3] = -5

print(l1)
print(l2)

【问题讨论】:

  • l2 = l1 赋值在 Python 中进行浅拷贝。要进行深层复制,请使用l2 = l1[:]
  • @PatrickHaugh 大错特错。 l2 = l1[:] 是浅拷贝。 l2 = l1 根本不是副本,只是绑定到同一个对象的另一个名称。
  • @wim,这都是术语。我认为l2 = l1 是一个(浅)副本。具体来说,是列表指针的副本。
  • 对不起,python 中没有指针之类的东西。下面都是字典(名称和对象)。
  • @AaronMcDaid l2 = l1 与浅拷贝的区别就像浅拷贝与深拷贝的区别一样。

标签: python list python-3.x oop inheritance


【解决方案1】:

很确定这对于 list 子类是不可能的。 可以使用 collections.UserList 子类(在 Python 中只需 UserList 2):

from collections import UserList

class MyList(UserList):

    def __init__(self, it=None):
        # keep reference only for list instances
        if isinstance(it, list):
            self.data = it
        else:
            super().__init__(it)

    def my_func(self):
        # do some stuff
        return self

UserList 公开了一个包含实际列表实例的data 属性,这一事实使我们很容易用可迭代的it 替换它,并且基本上只需将提供的参数放在那里并保留引用:

像你一样初始化:

l1 = list(range(10))
l2 = MyList(l1)

print(l1, l2, sep='\n')
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

然后变异:

l1[3] = -5

引用l1data 属性当然是变异的:

print(l1, l2, sep='\n')
[0, 1, 2, -5, 4, 5, 6, 7, 8, 9]
[0, 1, 2, -5, 4, 5, 6, 7, 8, 9]

【讨论】:

  • 所有 python2 读者的注意事项:这不是 py3 独有的功能,而是您直接 import UserList 而不是来自集合
  • 谢谢,这正是我想要的。
  • 根据 py3 文档__init__ 必须能够用零个或一个参数调用。 IE。您必须支持MyList()MyList([1,2,3])。经过一些试验,UserList 似乎默认为您处理所有这些,包括在必要时将范围和迭代转换为列表。
  • 另外,请参阅 bugs.python.org/issue27639 以了解 py3 版本的 UserList 和获取切片的错误。
  • @Dunes 谢谢,解决了这个要求。是的,它通过by wrapping them in a list call. 处理listUserList 以外的实例。还有,鬼鬼祟祟的虫子!
猜你喜欢
  • 1970-01-01
  • 2019-12-05
  • 1970-01-01
  • 2014-10-10
  • 2011-10-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多