Reputation: 1325
So I have in my project two classes: Circuit
and SubCircuit
. At some point I may need to construct a SubCircuit
from a Circuit
. Is there a more elegant way to do that than what's done below in the last 4 lines? Circuit
may get some new attributes at some point for example, which would mean that conversion would also need to be updated - basically inviting bugs.
class Gate(abc.ABC):
def __init__(self, size):
self.in_ports = (InPort(self),) * size
self.out_ports = (OutPort(self),) * size
class Circuit:
def __init__(self, size):
self.input = (OutPort(self),) * size
self.output = (InPort(self),) * size
self.gates = []
# ... some other stuff that messes around with these attributes
class SubCircuit(Gate, Circuit):
def __init__(self, circuit=None):
Gate.__init__(self, size)
Circuit.__init__(self, size)
if circuit is not None:
self.gates = circuit.gates
self.input = circuit.input
self.output = circuit.output
Upvotes: 1
Views: 270
Reputation: 110271
Bugs are already there - when you do self.gates = circuit.gates
, circuit.gates
being a list, yu point both references to the same list - and if this list is updated on the original circuit, this update will be reflected in your subcircuit
instance.
I think the most sane pattern tehre is to have an alternate constructor for the class if you have a circuit
instance from which to update your own:
from copy import copy
class SubCircuit(Gate, Circuit):
def __init__(self, size):
Gate.__init__(self, size)
Circuit.__init__(self, size)
@classmethod
def from_circuit(cls , circuit, size):
self = SubCircuit(size)
for key, value in circuit.__dict__.items():
setattr(self, key, copy(value))
return self
One "right" thing to do is to make the classes __init__
and other methods calling each other through the collaborative use of super()
instead of calling then explicitly by name - however, if your classes and subclasses are fixed to these 3, that may be a bit overkill, because Python's objects not handling extra parameters passed to its own __init__
method. (So, you'd have to verify in your base classes __init__
if they are the last ones prior to object
on the Method Resolution Order, and swallow the remaining args)
Upvotes: 1