定义具有大量属性的类的最干净方法是什么,每个属性都使用不同的参数调用相同的 setter 函数?
以下是我想要实现的目标。 这三个属性(red_LED等(中的每一个在设置时调用相同的 TalkToHardware(( 函数,但地址不同。 如您所见,这有效,但类定义冗长且笨拙。 它也容易出错。
class Hardware_Controller(object):
def __init__(self):
self.red_LED_address = 0
self.blue_LED_address = 1
self.green_LED_address = 2
@property
def red_LED(self):
return self._red_LED_status
@red_LED.setter
def red_LED(self,value):
self.TalkToHardware(self.red_LED_address,value)
self._red_LED_status = value
@property
def blue_LED(self):
return self._red_LED_status
@blue_LED.setter
def blue_LED(self,value):
self.TalkToHardware(self.blue_LED_address,value)
self._blue_LED_status = value
@property
def green_LED(self):
return self._red_LED_status
@green_LED.setter
def green_LED(self,value):
self.TalkToHardware(self.green_LED_address,value)
self._green_LED_status = value
def TalkToHardware(self,address,value):
print('Sending %i to address %i' % (value,address))
if __name__ == "__main__":
a = Hardware_Controller()
a.red_LED = 1
a.green_LED = 0
print(a.red_LED)
输出:
Sending 1 to address 0
Sending 0 to address 2
1
我希望类定义看起来更像这样:
class Hardware_Controller(object):
def __init__(self):
self.red_LED_address = 0
self.blue_LED_address = 1
self.green_LED_address = 2
self.red_LED = some_magic(self.red_LED_address)
self.blue_LED = some_magic(self.blue_LED_address)
self.green_LED = some_magic(self.green_LED_address)
def some_magic(address):
# Do magic things
pass
有没有一种干净的方法来实现这一点,仍然能够直接访问每个LED,如第一个示例的主要功能所示?
您可以创建一个函数,该函数仅定义并返回所需的property
类实例,然后使用它来定义类,从而摆脱所有重复的代码✶。
(如果不是很明显,下面代码中的LED_property()
函数对应于您问题中名为some_magic()
的函数。
class Hardware_Controller(object):
def LED_property(color_name):
""" Create and return a property for the given color_name. """
address_name = color_name + '_LED_address'
storage_name = '_' + color_name + '_LED_status'
@property
def prop(self):
return getattr(self, storage_name)
@prop.setter
def prop(self, value):
address = getattr(self, address_name)
self.TalkToHardware(address, value)
setattr(self, storage_name, value)
return prop
red_LED = LED_property('red')
blue_LED = LED_property('blue')
green_LED = LED_property('green')
def __init__(self):
self.red_LED_address = 0
self.blue_LED_address = 1
self.green_LED_address = 2
def TalkToHardware(self, address, value):
print('Sending %i to address %i' % (value, address))
del LED_property # Function isn't needed outside class definition.
if __name__ == "__main__":
a = Hardware_Controller()
a.red_LED = 1 # -> Sending 1 to address 0
a.green_LED = 0 # -> Sending 0 to address 2
print(a.red_LED) # -> 1
✶ 类似于 Python Cookbook(第三版(中 David Beazley 和 Brian Jones (2013( 中的配方"9.21 避免重复属性方法"。 我找到了整本书的PDF(8.8 Mb(,食谱在第382页。
也许你可以这样做:
def setter(self, address, value):
if address == self.red_LED_address:
attr = '_red_LED_status'
if address == self.blue_LED_address:
attr = '_blue_LED_status'
if address == self.green_LED_address:
attr = '_green_LED_status'
self.TalkToHardware(address, value)
setattr(self, attr, value) ## does this: self._XXX_LED_address = value
这是所有 LED 设置器功能的包罗万象功能。
我希望这是有帮助的!