3 回答

TA貢獻1773條經驗 獲得超3個贊
問題是由于僅在其當前范圍內import綁定名稱。在函數/方法中執行操作不會使其在其他方法中可用。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只需再次綁定名稱即可。這使得這種嵌套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

TA貢獻1712條經驗 獲得超3個贊
錯過了明顯的......
你可以這樣做:
from hardware import sysname
class Display(object):
def __init__(self, print_function, display_name):
self._print_function = print_function
self._display_name = display_name
def show(self, message):
self.print_function(message)
def __str__(self):
return self._display_name
def __repr__(self):
return self.__str__()
def create_display():
platform = sysname()
if platform == "RaspberryPi":
from rpi_display import writeline
return Display(writeline, "RPIDisplay")
elif platform == "Arduino":
from arduino_display import println
return Display(println, "ArduinoDisplay")
如果您需要類和嵌套工廠,您也可以應用相同的原則將函數對象存儲在那里。

TA貢獻1111條經驗 獲得超0個贊
問題是您導入的函數沒有保存在任何地方以供其他方法查看,因此它們在其他任何地方都不可見,只能在本地看到。ArduinoDisplay.arduino_display = arduino_display導入后嘗試設置。
這是一些示例代碼,可以說明我的意思:
class ADisplay:
def __init__(self):
from builtins import print as display_write
def show(self, msg):
display_write(msg)
disp = ADisplay()
disp.show("mymsg")
這失敗了NameError: name 'display_write' is not defined。
現在,將導入綁定到您的類。
class ADisplay:
def __init__(self):
from builtins import print as display_write
ADisplay.display_write = display_write
def show(self, msg):
self.display_write(msg)
disp = ADisplay()
disp.show("mymsg")
這行得通。事實上show,如果所有這些硬件打印方法僅將字符串作為參數并且您不需要格式化或修改任何內容,您甚至可以通過直接分配來省去它。
class ADisplay:
def __init__(self):
#do other init stuff...
pass
#only bind show the first time.
if getattr(ADisplay, "show", None):
return
from builtins import print as display_write
ADisplay.show = display_write
disp = ADisplay()
disp.show("mymsg")
添加回答
舉報