python - Elegant way to add functionality to previously defined functions -
how combine 2 functions together
i have class controlling hardware:
class heater() def set_power(self,dutycycle, period) ... def turn_on(self) ... def turn_off(self)
and class connects database , handles data logging functionality experiment:
class datalogger() def __init__(self) # record measurements , controls in database def start(self,t) # starts new thread acquire , record measuements every t seconds
now, in program recipe.py want like:
log = datalogger() @datalogger_decorator h1 = heater() log.start(60) h1.set_power(10,100) h1.turn_on() sleep(10) h1.turn_off() etc
where actions on h1 recorded datalogger. can change of classes involved, looking elegant way this. ideally hardware functions remain separated database , datalogger functions. , ideally datalogger reusable other controls , measurements.
for scenario, prefer using datalogger baseclass or mixin other classes rather trying sort of decorator magic (which doesn't click me pythonic way use decorator)
e.g.:
class datalogger(object): def __init__(self): # init stuff def startlog(self, t): # start log class heater(datalogger): def __init__(self): # stuff before initing datalogger super(heater, self).__init__() # init datalogger #other functions
that way can do:
h1 = heater() h1.startlog(5) h1.do_other_stuff()
an example uses mixin existing class:
class dataloggermixin(object): def __init__(self): # init things super(datalogger, this).__init__() # trigger next __init__ call in inheritance chain (i.e. whatever mix with) class heater(object): """ here's heater have lying around doesn't data logging. no need change it.""" # add new child class 2 lines, includes dataloggermixin first parent class, , have new class datalogging functionality , heater functionality. class loggingheater(dataloggermixin, heater): """ data logging heater """ pass # no further code should necessary if list dataloggermixin first in base classes. >>> logging_heater = loggingheater() >>> logging_heater.start_log(5) >>> logging_heater.do_heater_stuff()
the key using mixins in python understand how method resolution order (mro), particularly super, works in multiple inheritance situation. see this on cooperative multiple inheritance.
____________________________________________________________________
alternative method: use wrapper class
if mixin methodology doesn't work scheme, option use datalogger wrapper class objects logged. data logger accept object logging on in constructor so:
class datalogger(object) def __init__(self, object_to_log) self.object = object_to_log # have access self.object in methods. # record measurements , controls in database def start(self,t) # starts new thread aqcuire , reccord measuements every t secconds
i'm not sure type of logging or monitoring done , whether need access object you're logging or if independent. if former, presumably heater, valve, etc. implement same functions datalogger cares can log them regardless of class are. (this handy core feature of dynamic languages python called "duck typing", can operate on different types, long types implement functions or attributes care about. "if quacks duck . . .")
your code might more this, using wrapper class methodology:
h1 = heater() log = datalogger(h1) log.start(60) h1.set_power(10,100) h1.turn_on() sleep(10) h1.turn_off()
hope helps!
Comments
Post a Comment