TypeError:无法深拷贝此模式对象

18 投票
5 回答
12174 浏览
提问于 2025-04-16 19:10

我在我的“变量”类中遇到了一个错误,想弄明白这是怎么回事。

我原本想在“变量”类中存储一个 sre.SRE_Pattern 对象。我刚开始复制这个变量类,结果发现这导致我所有的变量类实例都发生了变化。现在我明白我需要对这个类进行深拷贝,但我又遇到了“TypeError: cannot deepcopy this pattern object”的错误。没错,我可以把模式存储为文本字符串,但我代码的其他部分已经期待一个编译好的模式了!那么,复制我的变量类并包含一个模式对象的最佳方法是什么呢?

import re
from copy import deepcopy

class VariableWithRE(object):
    "general variable class"
    def __init__(self,name,regexTarget,type):
        self.name = name
        self.regexTarget = re.compile(regexTarget, re.U|re.M) 
        self.type = type 

class VariableWithoutRE(object):
    "general variable class"
    def __init__(self,name,regexTarget,type):
        self.name = name
        self.regexTarget = regexTarget
        self.type = type 

if __name__ == "__main__":

    myVariable = VariableWithoutRE("myName","myRegexSearch","myType")
    myVariableCopy = deepcopy(myVariable)

    myVariable = VariableWithRE("myName","myRegexSearch","myType")
    myVariableCopy = deepcopy(myVariable)

5 个回答

5

在Python 3.7及以上版本,这个问题似乎已经解决了:

现在可以使用copy.copy()和copy.deepcopy()来复制编译好的正则表达式和匹配对象。(这个功能是Serhiy Storchaka在bpo-10076中贡献的。)

具体内容可以参考: https://docs.python.org/3/whatsnew/3.7.html#re

测试代码:

import re,copy

class C():
    def __init__(self):
       self.regex=re.compile('\d+')

myobj = C()    
foo = copy.deepcopy(myobj)
foo.regex == myobj.regex
# True
8

在3.7版本之前的Python中,可以通过修改copy模块来解决这个问题:

import copy
import re 

copy._deepcopy_dispatch[type(re.compile(''))] = lambda r, _: r

o = re.compile('foo')
assert copy.deepcopy(o) == o
11

deepcopy 是一个函数,它对你的类(也就是你自己定义的对象类型)并不了解,所以它不知道怎么去复制这些对象。

你可以通过实现一个叫做 __deepcopy__() 的方法,来告诉 deepcopy 应该如何复制你的对象:

class VariableWithoutRE(object):
   # ...
   def __deepcopy__(self):
      return VariableWithoutRE(self.name, self.regexTarget, self.type)

撰写回答