copy.deepcopy使用自定义__new __()方法在对象上引发TypeError [英] copy.deepcopy raises TypeError on objects with self-defined __new__() method

查看:72
本文介绍了copy.deepcopy使用自定义__new __()方法在对象上引发TypeError的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我想实现一个符号类型,该符号类型跟踪我们已经拥有的符号(保存在 _sym_table 中),如果存在则返回它们,或者创建新的除此以外。代码:

I want to implement a symbol type, which keeps track of the symbols we already have(saved in _sym_table), and return them if they exist, or create new ones otherwise. The code:

# -*- coding: utf-8 -*-

_sym_table = {}

class Symbol(object):
    def __new__(cls, sym):
        if sym not in _sym_table:
            return super().__new__(cls)
        else:
            return _sym_table[sym]

    def __init__(self, sym):
        self.sym = sym
        _sym_table[sym] = self

    def __str__(self):
        return self.sym

    def __cmp__(self, other):
        return self is other

    def __hash__(self):
        return self.sym.__hash__()

但是当我在此类 Symbol 实例的列表中调用 copy.deepcopy 时,会引发异常:

But when I call copy.deepcopy on a list of such Symbol instances, exception is raised:

a = Symbol('a')
b = Symbol('b')
s = [a, b]
t = copy.deepcopy(s)

错误消息:

Traceback (most recent call last):
  File "xxx.py", line 7, in <module>
    t = copy.deepcopy(s)
  File "/usr/lib/python3.2/copy.py", line 147, in deepcopy
    y = copier(x, memo)
  File "/usr/lib/python3.2/copy.py", line 209, in _deepcopy_list
    y.append(deepcopy(a, memo))
  File "/usr/lib/python3.2/copy.py", line 174, in deepcopy
    y = _reconstruct(x, rv, 1, memo)
  File "/usr/lib/python3.2/copy.py", line 285, in _reconstruct
    y = callable(*args)
  File "/usr/lib/python3.2/copyreg.py", line 88, in __newobj__
    return cls.__new__(cls, *args)
TypeError: __new__() takes exactly 2 arguments (1 given)

所以我的问题是:


  • 如何使用自定义的 __ new __ 方法?

  • 以及有关何时以及如何使用 copy.deepcopy 的任何建议?

  • How can I make a deep copy on these objects with self-defined __new__ methods?
  • And any suggestions about when and how to use copy.deepcopy?

非常感谢!

推荐答案

一个问题是 deepcopy copy 无法知道将哪些参数传递给 __ new __ ,因此它们仅适用于不需要构造函数参数的类。

one problem is that deepcopy and copy have no way of knowing which arguments to pass to __new__, therefore they only work with classes that don't require constructor arguments.

拥有 __ init __ 参数是在复制对象时不会调用 __ init __ ,而是 __ new __

the reason why you can have __init__ arguments is that __init__ isn't called when copying an object, but __new__ must be called to create the new object.

因此,如果要控制复制,则必须定义特殊的 __ copy __ __ deepcopy __ 方法:

so if you want to control copying, you'll have to define the special __copy__ and __deepcopy__ methods:

def __copy__(self):
    return self

def __deepcopy__(self, memo):
    return self

顺便说一句,单子邪恶,而在python中并不需要。

by the way, singletons are evil and not really needed in python.

这篇关于copy.deepcopy使用自定义__new __()方法在对象上引发TypeError的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆