【问题标题】:Python deepcopy of list on assignment分配列表的Python深拷贝
【发布时间】:2012-03-15 01:40:30
【问题描述】:

在 python 考试中得到了这个练习。 试图返回这样的列表的深层副本:

l = list()
l = [0,1,2]
l1 = l
l[0] = 1

l1 应该包含[0,1,2] 而不是[1,1,2]

指定使用元类实现它的练习。

class deep(type):
    def __new__(meta, classname, bases, classDict):
        return type.__new__(meta, classname, bases, classDict)
    def __init__(cls, name, bases, dct):
        super(deep, cls).__init__(name, bases, dct)
    def __call__(cls, *args, **kwds):
        return type.__call__(cls, *args, **kwds)            
class list(metaclass=deep):
    def __init__(self):
        pass

据我所知,python 中的'=' 是一个语句,而不是一个运算符,它不能被覆盖。关于如何在作业中返回深层副本的任何想法?尝试了很多,但没有成功。

【问题讨论】:

  • 简而言之,你不能。即使某些巧妙的黑客找到了方法,也不应该永远使用它。相信我,我不会轻易做出这样笼统的陈述。
  • 这是一个非常奇怪的练习,因为您可以使用切片符号 (l1 = l[:]) 执行仅包含三个字符的深层复制。在这里使用元类感觉有点矫枉过正。
  • 如果这是学校的考试题,我建议你直接关闭它。要求我们帮助你的考试是学术作弊的高度。
  • @S.Lott:也许考试已经结束了。至少,它应该被标记为homeworkexam
  • @Frederic Hamidi:也许在您的python版本中,您可以通过这种方式进行深度复制,大多数其他人需要from copy import deepcopyb=deepcpy(a)否则只有主列表被复制,而所有嵌套的容器类都是保留在新列表中作为参考!您可以使用例如:for l in (a,b): id(l); map (id,l) 进行检查

标签: python list deep-copy metaclass


【解决方案1】:

据我所知,如果不使用某种额外的语法,这在 python 中是不可能的。正如你所说,你不能覆盖=

【讨论】:

  • 但他可能会使用__repr__ 方法来获得类似的结果!只是不返回一个字符串而是一个新的类!
  • @DonQuestion:__repr__ 是否调用绑定名称?这似乎很奇怪。
  • @Daenyth 不是。唐问题偏离了轨道。
  • @DonQuestion 我也尝试使用 repr,通过返回 copy.deepcopy(self),但 python 返回:TypeError: repr 返回非字符串(类型列表),因为它只需要 repr 我认为的字符串
  • 我不是指repr(),而是带有两个下划线的特殊方法__repr__。尽管如此,delnan 是正确的,因为您似乎无法以这种方式复制。我之前没有测试过,所以我偏离了轨道。对不起!
【解决方案2】:

要了解 l1 = l 在 Python 中的作用,请阅读 Other languages have "variables", Python has "names"

要更改l[0] = 1 的内容,您可以覆盖l__setitem__() 方法:

>>> class L(list):
...     def __setitem__(self, i, v):
...         list.__setitem__(self, i, 10)
... 
>>> l = L()
>>> l.append(1)
>>> l
[1]
>>> l[0] = 0
>>> l
[10]

要更改 l = List(); l = [0,1,2] 的作用,您可以在 CPython 中定义 List.__del__() 方法并操作 l 所属的命名空间,例如,使用 inspect 模块。不用说你不应该那样做。

>>> import inspect
>>> class L:
...     def __del__(self):
...         inspect.currentframe().f_globals['l'] = [1,2,3]
... 
>>> l = L()
>>> l = [0]
>>> l
[1, 2, 3]

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2015-01-13
    • 1970-01-01
    • 2014-05-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-20
    相关资源
    最近更新 更多