对于这种情况,我更喜欢将 DataLogger 作为 BaseClass 或 Mixin 用于其他类,而不是尝试做某种装饰器魔术(这对我来说并没有真正点击作为使用装饰器的 Pythonic 方式)
例如:
class DataLogger(object):
def __init__(self):
# do init stuff
def startlog(self, t):
# start the log
class Heater(DataLogger):
def __init__(self):
# do some stuff before initing your dataLogger
super(Heater, self).__init__() # init the DataLogger
#other functions
这样你就可以这样做:
h1 = Heater()
h1.startlog(5)
h1.do_other_stuff()
将其用作现有类的 mixin 的示例:
class DataLoggerMixin(object):
def __init__(self):
# do your init things
super(DataLogger, this).__init__() # this will trigger the next __init__ call in the inheritance chain (i.e. whatever you mix it with)
class Heater(object):
""" Here's a heater you have lying around that doesn't do data logging. No need to change it."""
# add a new child class with 2 lines, that includes the DataLoggerMixin as the first parent class, and you will have a new class with all the DataLogging functionality and the Heater functionality.
class LoggingHeater(DataLoggerMixin, Heater):
""" Now its a data logging heater """
pass # no further code should be necessary if you list DataLoggerMixin first in the base classes.
>>> logging_heater = LoggingHeater()
>>> logging_heater.start_log(5)
>>> logging_heater.do_heater_stuff()
在 python 中成功使用 mixins 的关键是了解方法解析顺序 (MRO),特别是对于 super,如何在多重继承情况下工作。请参阅协作多重继承。
____________________________________________________________________
替代方法:使用包装类
如果 Mixin 方法不适用于您的方案,另一种选择是使用 DataLogger 作为要记录的对象的包装类。基本上,Data Logger 将接受一个对象在其构造函数中进行登录,如下所示:
class DataLogger(object)
def __init__(self, object_to_log)
self.object = object_to_log # now you have access to self.object in all your methods.
# Record measurements and controls in a database
def start(self,t)
# Starts a new thread to aqcuire and reccord measuements every t secconds
我不确定完成了哪种类型的日志记录或监控,以及您是否需要访问正在记录的对象,或者它是否是独立的。如果前者,大概是 Heater、Valve 等都实现了 DataLogger 关心的相同功能,那么无论它们是什么类,您都可以为它们记录。(这是 Python 等动态语言的一个方便的核心功能,称为“鸭子类型”,您可以在其中对不同的类型进行操作,只要这些类型实现了您关心的功能或属性。“如果它像鸭子一样嘎嘎叫...... ")
您的代码可能看起来更像这样,使用包装类方法:
h1 = Heater()
log = DataLogger(h1)
log.start(60)
h1.set_power(10,100)
h1.turn_on()
sleep(10)
h1.turn_off()
希望这可以帮助!