Я хочу создать абстрактную фабрику, чтобы абстрагировать аппаратные различия между компьютерами (например, RaspberryPi и Arduino) в Python 2.7.
Я использую следующую реализацию абстрактной фабрики:
'''
Provide a device-agnostic display interface
'''
from hardware import sysname
class DisplayBase(object):
def __init__(self):
pass
def show(self, message):
pass
def __str__(self):
return "DisplayBase"
def __repr__(self):
return self.__str__()
class RPIDisplay(DisplayBase):
def __new__(cls, *args, **kwargs):
from rpi_display import writeline
instance = super(RPIDisplay, cls).__new__(cls, *args, **kwargs)
return instance
def __str__(self):
return "RPIDisplay"
def show(self, message):
writeline(message)
class ArduinoDisplay(DisplayBase):
def __new__(cls, *args, **kwargs):
import arduino_display
instance = super(ArduinoDisplay, cls).__new__(cls, *args, **kwargs)
return instance
def __str__(self):
return "ArduinoDisplay"
def show(self, message):
return arduino_display.println(message)
class Display(DisplayBase): # Display Factory
def __new__(cls, *args, **kwargs):
platform = sysname()
if platform == "RaspberryPi":
return RPIDisplay()
elif platform == "Arduino":
return ArduinoDisplay()
else:
return MockDisplay()
if __name__ == "__main__":
display = Display()
print display
display.show("hello world")
Инстанцирование работает нормально, но когда я пытаюсь запустить это, я получаю:
ArduinoDisplay
Traceback (most recent call last):
File "tt.py", line 56, in <module>
display.show("hello world")
File "tt.py", line 41, in show
return arduino_display.println(message)
NameError: global name 'arduino_display' is not defined
Так что импорт arduino_display
работает, но я не могу найти способ чтобы использовать его в объекте.
Необходим условный импорт, поскольку на разных платформах будут установлены разные модули.
Есть идеи, как использовать этот условный импорт?
Я пытался self.arduino_display
и ArduinoDisplay.arduino_display
, но безрезультатно.
Я, очевидно, мог бы отследить ошибки импорта, например, добавить в начало:
try:
import arduino_display
except:
pass
... и это не получится на RPI, что было бы хорошо, но должен быть лучший способ ...