<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                企業??AI智能體構建引擎,智能編排和調試,一鍵部署,支持知識庫和私有化部署方案 廣告
                # 練習 30:有限狀態機 > 原文:[Exercise 30: Finite State Machines](https://learncodethehardway.org/more-python-book/ex30.html) > 譯者:[飛龍](https://github.com/wizardforcel) > 協議:[CC BY-NC-SA 4.0](http://creativecommons.org/licenses/by-nc-sa/4.0/) > 自豪地采用[谷歌翻譯](https://translate.google.cn/) 每當你閱讀一本關于解析的書,都有一個可怕的章節,關于有限狀態機(FSM)。他們對“邊”和“節點”進行了詳細的分析,每個可能的“自動機”的組合被轉換成其他自動機,坦率地說,它有點多了。FSM 有一個更簡單的解釋,使得它們實用并且可理解,而不會違背相同主題的純理論版本。當然你不會向 ACM 提交論文,因為你不知道 FSM 背后的所有數學知識,但如果你只想在應用程序中使用它們,那么它們就足夠簡單了。 FSM 是組織事件一種方式,事件發生在一系列狀態上。定義事件的另一種方法是“輸入觸發器”,類似于`if`語句中的布爾表達式,但通常不太復雜。事件可以是按鈕點擊,從流中接收字符,更改日期或時間,以及幾乎任何用于聲明事件的東西。狀態就是你的 FSM 停止的任何“位置”,同時它等待更多的事件,并且你定義的每個狀態都允許事件(輸入)。事件往往是暫時的,而狀態通常是固定的,而且二者都是可以存儲的數據。最后,你可以將代碼附加到事件或狀態,甚至決定在進入狀態時,狀態中或退出狀態時是否應運行代碼。 FSM 只是一種方法,在執行中不同位置發生不同事件時,使用白名單列出可能運行的代碼。在 FSM 中,當你收到意外事件時,你會發生故障,因為你必須明確說明每個狀態允許哪些事件(或條件)。`if`語句也可以處理可能的分支,但它是一個可能性的黑名單。如果你忘記了`else`子句,那么你的`if-elif`條件沒有覆蓋的任何東西都會退回默認。 讓我們將其拆解: + 你擁有狀態,這是 FSM 當前所在位置的存儲指示器。狀態可以是“開始”,“按下某鍵”,“中止”或類似的方式,描述執行的可能位置中的 FSM 的位置。每個狀態都意味著正在等待某事發生,在決定下一步做什么之前。 + 你擁有事件,可以將 FSM 從一個狀態移動到另一個狀態。事件可以是“按下某鍵”,“套接字連接失敗”,“文件保存”,并表示 FSM 接收到一些外部刺激,因此必須決定要做什么,以及下一個狀態是什么。一個事件甚至可以回到同一個狀態,這是你循環的方式。 + 根據發生的事件,FSM 從一個狀態轉換到另一個狀態,并且僅僅由于為狀態提供的確切事件(盡管其中一個事件可以定義為“任何事件”)。他們不會“意外”轉移狀態,你可以通過查看收到的事件和訪問的狀態,精確地跟蹤他們從一個狀態轉移到另一個狀態。這使得它們非常容易調試。 + 在狀態轉換之前,之后和期間,你可以在每個事件上運行代碼。這意味著你可以在收到事件時運行一些代碼,然后決定在該狀態下基于該事件做什么,然后在離開該狀態之前再次運行代碼。這種執行代碼的功能使得 FSM 非常強大。 + 有時候“沒有”也是一個事件。這很好很強大,因為這意味著即使沒有發生任何事情,你也可以將 FSM 轉換到新的狀態。然而,實際上,“沒有”往往是隱含的事件“再來一次”或“醒來”。在其他情況下,這個狀態的意思是,“不確定,也許下一個事件會告訴我是什么狀態。” FSM 的力量是能夠明確地說明每個事件,事件只是正在接收的數據。這使得它們非常容易進行調試,測試和正確實現,因為你確切地知道每個狀態的可能性,以及在每個狀態中,對于每個事件可能發生的情況。在本練習中,你將要研究 FSM 庫和使用它的 FSM 實現,來了解它們如何工作。 ## 挑戰練習 我創建了一個 FSM 模塊,處理一些簡單的事件來處理 Web 服務器的連接。這是一個虛構的 FSM,為你提供一個在 Python 中快速編寫 FSM 的例子。它只是處理連接的基本框架,連接從套接字讀取和寫入,并且它缺少一些重要的東西,但這只是供你使用的一個很小的例子。 ```py def START(): return LISTENING def LISTENING(event): if event == "connect": return CONNECTED elif event == "error": return LISTENING else: return ERROR def CONNECTED(event): if event == "accept": return ACCEPTED elif event == "close": return CLOSED else: return ERROR def ACCEPTED(event): if event == "close": return CLOSED elif event == "read": return READING(event) elif event == "write": return WRITING(event) else: return ERROR def READING(event): if event == "read": return READING elif event == "write": return WRITING(event) elif event == "close": return CLOSED else: return ERROR def WRITING(event): if event == "read": return READING(event) elif event == "write": return WRITING elif event == "close": return CLOSED else: return ERROR def CLOSED(event): return LISTENING(event) def ERROR(event): return ERROR ``` 也有一個小測試,向你展示如何運行這個 FSM: ```py import fsm def test_basic_connection(): state = fsm.START() script = ["connect", "accept", "read", "read", "write", "close", "connect"] for event in script: print(event, ">>>", state) state = state(event) ``` 你在本練習中的挑戰是,將此示例模塊變成一個更強大和通用的 FSM Python 類。你應該使用它作為一系列線索,來了解如何處理進入的事件,狀態如何作為 Python 函數,以及如何進行隱式的轉換。看看我有時候為下一個狀態返回函數,但其??他時候我會返回一個狀態函數的調用?試著弄清楚為什么我會這樣做,因為它在 FSM 中非常重要。 為了完成這個挑戰,你需要學習 Python [`inspect`](https://docs.python.org/3/library/inspect.html)模塊,看看你可以用 Python 對象和類來做什么。有一些特殊的變量,如`__dict__`以及`inspect`中的函數,可幫助你窺探類或對象并查找函數。 你也可以決定要反轉此設計。你可以將事件作為子類中的函數,并在事件函數內檢查當前的`self.state`,來確定接下來要執行的操作。這完全都取決于你正在處理什么,你是否擁有更多的事件還是狀態,當時什么有意義。 最后,你可以使用一個設計,其中有一個`FSMRunner`類,它只知道如何運行這樣設計的模塊。這比一個知道如何運行自身實例的單一類有一些優點,但也有一些問題。例如,`FSMRunner`如何跟蹤當前狀態?它放在模塊中還是在`FSMRunner`的實例中? ## 研究性學習 + 使你的測試更加泛用,并為你熟悉的完全不同的領域做一個FSM。 + 添加一個功能,啟動在你的實現中運行的事件的日志。使用 FSM 處理事件的最大優點之一是,可以存儲和記錄 FSM 收到的所有事件和狀態。這可以讓你調試,為什么它達到你不需要的狀態。 ## 深入學習 你應該仔細研究 FSM 背后的數學。我這里的小例子不是完全形式化的概念版本,以便你能理解它。
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看