TypeError: не может выполнить глубокую копию этого объекта шаблона

Попытка понять эту ошибку в моем классе "Variable".

Я надеялся сохранить sre.SRE_Pattern в моем классе "Variable". Я только начал копировать класс Variable и заметил, что он вызывает изменение всех экземпляров класса Variable. Теперь я понимаю, что мне нужно сделать глубокий поиск этого класса, но теперь я натыкаюсь на "TypeError: не может сделать глубокий поиск этого объекта шаблона". Конечно, я могу сохранить шаблон как текстовую строку, но остальная часть моего кода уже ожидает скомпилированный шаблон! Каким будет лучший способ скопировать мой класс Variable с объектом шаблона?

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)

Ответ 1

deepcopy ничего не знает о ваших классах и не знает, как их скопировать.

Вы можете сказать deepcopy, как копировать свои объекты, внедряя метод __deepcopy__():

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

Ответ 2

Кажется, это исправлено в Python версии 3. 7+:

Скомпилированные объекты регулярного выражения и соответствия теперь можно копировать с помощью copy.copy() и copy.deepcopy(). (Внесено Сергеем Сторчака в 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

Ответ 3

Кажется, проблема в скомпилированном регулярном выражении. deepcopy не может справиться с ними.

Минимальный пример дает мне ту же ошибку:

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

myobj = C()    
copy.deepcopy(myobj)

Это выдает ошибку: TypeError: cannot deepcopy this pattern object. Я в Python3.5.

Ответ 4

Это можно обойти, исправив модуль copy в python до 3.7:

import copy
import re 

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

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