From c7ea6bc5a6f95df456b4177641ee4a5c13a8cc53 Mon Sep 17 00:00:00 2001 From: Daniel Brown <ddb@star.sr.bham.ac.uk> Date: Wed, 15 Apr 2015 13:35:27 +0100 Subject: [PATCH] updates --- pykat/detectors.py | 59 +++++++++++++++++++++-------- pykat/finesse.py | 2 +- test/test_deepcopying_references.py | 2 + 3 files changed, 47 insertions(+), 16 deletions(-) diff --git a/pykat/detectors.py b/pykat/detectors.py index a14bfbc..42ddc58 100644 --- a/pykat/detectors.py +++ b/pykat/detectors.py @@ -30,7 +30,9 @@ from pykat import USE_GUI, NoGUIException if USE_GUI: import pykat.gui.resources from pykat.gui.graphics import * - + +id___ = 0 + class BaseDetector(object) : """ This is a base class for all detectors. Classes Detector1 and Detector2 should be used directly. @@ -39,6 +41,18 @@ class BaseDetector(object) : __metaclass__ = abc.ABCMeta + def __new__(cls, *args, **kwargs): + # This creates an instance specific class for the component + # this enables us to add properties to instances rather than + # all classes + global id___ + id___ += 1 + cnew_name = str("%s.%s_%i" % (cls.__module__, cls.__name__, id___)) + + cnew = type(cnew_name, (cls,), {}) + + return object.__new__(cnew, *args, **kwargs) + def __init__(self, name, nodes=None, max_nodes=1): self.__name = name @@ -81,6 +95,19 @@ class BaseDetector(object) : self._requested_nodes.append(nodes) else: raise pkex.BasePyKatException("Nodes should be a list or tuple of node names or a singular node name as a string.") + + def __deepcopy__(self, memo): + """ + When deep copying a kat object we need to take into account + the instance specific properties. + """ + + # Here we create a copy of this object based of the base class + # of this one, otherwise we're making a copy of a copy of a copy... + result = self.__class__.__new__(self.__class__.__base__) + result.__dict__ = copy.deepcopy(self.__dict__, memo) + + return result def _register_param(self, param): self._params.append(param) @@ -412,20 +439,22 @@ class pd(Detector1): self.__set_demod_attrs() - def __deepcopy__(self, memo): - """ - When deep copying a kat object we need to take into account - the instance specific properties. - """ - result = pd(self.name, self.num_demods, self.node.name) - memo[id(self)] = result - result.__dict__ = copy.deepcopy(self.__dict__, memo) - # Find all properties in class we are copying - # and deep copy these to the new class instance - for x in self.__class__.__dict__.items(): - if isinstance(x[1], property): - setattr(result.__class__, x[0], x[1]) - return result + # def __deepcopy__(self, memo): + # """ + # When deep copying a kat object we need to take into account + # the instance specific properties. + # """ + # result = pd(self.name, self.num_demods, self.node.name) + # memo[id(self)] = result + # result.__dict__ = copy.deepcopy(self.__dict__, memo) + # + # # Find all properties in class we are copying + # # and deep copy these to the new class instance + # for x in self.__class__.__dict__.items(): + # if isinstance(x[1], property): + # setattr(result.__class__, x[0], x[1]) + # + # return result @property def senstype(self): return self.__senstype diff --git a/pykat/finesse.py b/pykat/finesse.py index 287a815..b9dc5cb 100644 --- a/pykat/finesse.py +++ b/pykat/finesse.py @@ -492,7 +492,7 @@ class kat(object): same properties regardless of whether they have the actual object added to it. So we create an instance specific class. """ - result = self.__class__.__new__(self.__class__) + result = self.__class__.__new__(self.__class__.__base__) memo[id(self)] = result result.__dict__ = copy.deepcopy(self.__dict__, memo) diff --git a/test/test_deepcopying_references.py b/test/test_deepcopying_references.py index 04ad099..42d173e 100644 --- a/test/test_deepcopying_references.py +++ b/test/test_deepcopying_references.py @@ -8,6 +8,8 @@ from copy import deepcopy kat0 = pykat.finesse.kat() kat0.parseCommands("m m1 1 0 0 n0 n1") +kat0.parseCommands("pd o0 n1") +kat0.parseCommands("pd1 o1 1 0 n1") kat1 = deepcopy(kat0) -- GitLab