亚洲在线久爱草,狠狠天天香蕉网,天天搞日日干久草,伊人亚洲日本欧美

為了賬號安全,請及時綁定郵箱和手機立即綁定
已解決430363個問題,去搜搜看,總會有你想問的

從 python 抽象工廠中導入

從 python 抽象工廠中導入

慕田峪9158850 2022-07-12 17:56:49
我想創建一個抽象工廠,以便在 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_display,ArduinoDisplay.arduino_display但無濟于事。
查看完整描述

3 回答

?
慕容3067478

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


查看完整回答
反對 回復 2022-07-12
?
交互式愛情

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")


如果您需要類和嵌套工廠,您也可以應用相同的原則將函數對象存儲在那里。


查看完整回答
反對 回復 2022-07-12
?
catspeake

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")


查看完整回答
反對 回復 2022-07-12
  • 3 回答
  • 0 關注
  • 162 瀏覽
慕課專欄
更多

添加回答

舉報

0/150
提交
取消
微信客服

購課補貼
聯系客服咨詢優惠詳情

幫助反饋 APP下載

慕課網APP
您的移動學習伙伴

公眾號

掃描二維碼
關注慕課網微信公眾號