2016-03-04 1 views
0

У меня есть иерархия классов, представляющая выражение линейной алгебры (как деревья выражений), что-то вроде этого (это на самом деле сложнее, но этого должно быть достаточно, чтобы дать вам представление).Python: custom deepcopy в иерархии классов

  • Expression
    • Оператор
      • Времена
      • Plus
    • Символ
      • Матрица
      • Скалярного

Я манипулируя эти выражения в самых разных формах, так что я должен скопировать это выражению: много, потому что я хочу, чтобы изучить различные способы манипулирования им (я действительно не» так и не копируйте их). Неудивительно, что copy.deepcopy() работает медленно.

Не все атрибуты класса должны быть подвергнуты глубокой печати, и эти деревья выражений всегда будут деревьями (если нет, что-то в корне неверно), поэтому я могу сэкономить некоторое время, упростив memoization (или не использую его в все).

Я хочу ускорить копирование, выполнив специальную функцию копирования. Это может означать реализацию __deepcopy__(), написав совершенно новую функцию или используя что-то вроде get_state и set_state, мне действительно все равно. На данный момент я не забочусь о травлении.

Я использую Python 3.

Поскольку у меня есть этот класс иерархии, где новые атрибуты вводятся на разных уровнях, я предпочел бы не начинать с нуля на каждом уровне. Вместо этого было бы желательно повторно использовать некоторую функциональность суперкласса, аналогичную тому, как в __init__, обычно называет __init__ суперкласса. Тем не менее, я бы предпочел не называть __init__, потому что это иногда делает некоторые дополнительные вещи, которые не нужны при копировании.

Как мне сделать это самым быстрым и самым питоническим способом? Я не смог найти никаких разумных рекомендаций относительно того, как реализовать эту функцию копирования в этих обстоятельствах. Я рассмотрел реализацию deepcopy как в Python 2, так и 3. В Python 2 используется множество различных методов (get_state/set_state, используя __dict__, ...), в Python 3, я не могу найти соответствующую функцию вообще.

ответ

1

я нашел одно из возможных решений себе:

class Expression(object): 
    ... 
    def __deepcopy__(self, memo): 
     cpy = object.__new__(type(self)) 
     # manually copy all attributes of Expression here 
     return cpy 

class Operator(Expression): 
    ... 
    def __deepcopy__(self, memo): 
     cpy = Expression.__deepcopy__(self, memo) 
     # manually copy all attributes exclusive to Operator here 
     return cpy 

Новый объект всегда создается в __deepcopy__ из Expression. Используя object.__new__(type(self)), новый объект имеет тип объекта, на котором первоначально был вызван __deepcopy__ (например, Operator).

К сожалению, это решение не намного быстрее, чем по умолчанию.Мне интересно, если это из-за всех этих вызовов до __deepcopy__ вплоть до вершины иерархии классов. Я исследую это.

Смежные вопросы