gpt4 book ai didi

python - 从 python 抽象工厂中导入

转载 作者:行者123 更新时间:2023-12-01 04:23:24 26 4
gpt4 key购买 nike

我想创建一个抽象工厂,以便在 Python 2.7 中抽象计算机(比如 RaspberryPi 和 Arduino)之间的硬件差异。

我正在使用抽象工厂的以下实现:

  '''
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_displayArduinoDisplay.arduino_display但无济于事。

我显然可以捕获导入错误,例如添加到顶部:
    try:
import arduino_display
except:
pass

...这会在 RPI 上失败,这很好,但必须有更好的方法...

最佳答案

问题是由于 import仅在其当前范围内绑定(bind)名称。做一个import在函数/方法中不会使其在其他方法中可用。

在您实际需要的地方执行导入。例如,ArduinoDisplay应该导入 arduino_display在哪里使用:

class ArduinoDisplay(DisplayBase):
# no new, no import

def __str__(self):
return "ArduinoDisplay"

def show(self, message):
# import where needed
import arduino_display
return arduino_display.println(message)

请注意 import是幂等的——如果模块之前已经加载过, import只是再次绑定(bind)名称。这使得这样的嵌套 import对于大多数情况,语句足够快。

如果您的类需要大量导入或速度存在问题,请将类隔离到单独的模块中并有条件地导入整个模块。您可以使用通用名称直接分配正确的类,而不是使用构造另一个的虚拟类型。
# ## display/arduino.py ##
# other systems accordingly
from .base import DisplayBase

# import once, globally
import arduino_display

class ArduinoDisplay(DisplayBase):
# no new, no import

def __str__(self):
return "ArduinoDisplay"

def show(self, message):
# import where needed
return arduino_display.println(message)

# ## display/__init__.py ##
from hardware import sysname

platform = sysname()
# resolve and import appropriate type once
if platform == "RaspberryPi":
from .rpi import RPIDisplay as Display
elif platform == "Arduino":
from .arduino import ArduinoDisplay as Display
else:
from .mock import MockDisplay as Display

关于python - 从 python 抽象工厂中导入,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59984507/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com