Reputation: 375
I have a Python script that controls a list
of imaginary machines that have to walk above the lines of a given image.
I have a Control
class that keeps track of all the instances of Machine
and updates the instance's position and rotation. Due to some imperfections in the image, some instances can and will get lost so that they need to have their position "manually" recalculated.
The problem is that I need to apply a method in all the instances selected and returned in a list
object without breaking the chain of function calls.
This is what I have:
class Control:
def __init__(self, instances):
self.machine_instances = instances
...
def get(self, elem = 0, end = None, step = 1):
return machine_instances[elem : end : step]
...
class Machine:
def __init__(self, x_position):
...
def position_recalc(self):
...
...
This is how it must be used:
ml = [Machine(int(sys.argv[i])) for i in range(1, sys.argc)]
c = Control(ml)
...
c.get(2, 4).position_recalc()
OBS: The method Control.get()
may have its return value and type changed.
Upvotes: 0
Views: 114
Reputation: 12401
using a self return to simplify this a bit. this is one way to implement a modifiable interface:
class Control(object):
def __init__(self, instances):
self.focus = None
self.instances = instances
def get(self, start=None, end=None, slice=None):
self.focus = (start, end, slice)
return self
def position_recalc(self):
if self.focus == None:
self.focus = (None, None, None)
for i in self.instances.__getitem__(slice(*self.focus)):
i.position_recalc()
self.focus = None
c.get(2,4).position_recalc()
c.get(2,4)
returns the same item, but sets a context for it, and returns the same object to the user, which is necessary so position_recalc
has an object to work on. there's probably a general pattern for this (delegator?), this is an unusual form for it but still the same general pattern.
Upvotes: 0
Reputation: 34146
You could create a class SelectedMachines
:
class SelectedMachines:
def __init__(self, selected):
self.selected_machines = selected
def position_recalc(self):
for machine in self.selected_machines:
machine.someFunction()
So you can return a SelectedMachines object in Control.get()
:
class Control:
def __init__(self, instances):
self.machine_instances = instances
...
def get(self, elem = 0, end = None, step = 1):
return SelectedMachines(machine_instances[elem : end : step])
...
Where someFunction()
is a method that applies recalculates position of one specific machine.
Upvotes: 1
Reputation: 304255
Looks like you need to return something like a list
with a position_recalc
method
class ListWithReCalc(list):
def position_recalc(self):
...
class Control:
def __init__(self, instances):
self.machine_instances = instances
...
def get(self, elem = 0, end = None, step = 1):
return ListWithReCalc(machine_instances[elem : end : step])
Otherwise you can use composition
class ThingWithReCalc(object):
def __init__(self, items):
self.items = items()
def position_recalc(self):
for i in self.items():
i.position_recalc()
class Control:
def __init__(self, instances):
self.machine_instances = instances
...
def get(self, elem = 0, end = None, step = 1):
return ListWithReCalc(machine_instances[elem : end : step])
Upvotes: 1