2012-03-05 36 views
2

我目前正在做一個實驗,在那裏我正在實現一箇舊的遊戲腳本語言的解釋器。這是一種基於第四語言,所以我認爲將指令(一旦驗證和完全處理)放入一個大名單將是相當容易的。如何根據列表條目調用函數?

一旦我得到了列表中的代碼,我試圖遍歷整個程序中的for循環,每次處理一條指令。某些項目,比如字符串,可以放在一個保存當前棧的變量上,這很容易。但是我卡住的地方是發生命令。

我有一個有效的函數的大清單,我希望它在任何指令匹配的地方都會調用相關的函數。

因此,舉例來說,如果我有:

"Hello, world!" notify 

...代碼將檢查通知在列表中,然後執行通知功能。底線是:如何將字符串轉換爲函數名稱?

+0

所以你想''你好,世界!「 notify'表現得像'notify(「Hello,world!」)'? – 2012-03-05 19:23:22

+0

嗯,它實際上會調用通知函數,它會採用堆棧變量並彈出所需的項目來執行通知,但或多或​​少,是的。 – Kelketek 2012-03-05 19:25:33

+0

我不熟悉Python中的正則表達式使用,但它看起來像你必須匹配字符串與引號(排他性)中的所有內容,並確保您檢查轉義的引號。然後您將使用捕獲組來確定要調用哪個函數。解析總是很麻煩。 – 2012-03-05 19:28:52

回答

4

你可以保持功能的字典中的代碼可以調用,然後做一個仰望的時候,你需要:

def notify(s): 
    print(s) 

d = {"notify": notify} 

d["notify"]("Hello, world!") 
+0

這不就是調用通知函數並將其結果放在該字典的值中嗎? – Kelketek 2012-03-05 19:30:18

+3

python中的函數是第一類對象,'notify'只是綁定到該函數的名稱(嘗試代碼,它按原樣運行)。 – strcat 2012-03-05 19:31:27

+0

工作就像一個魅力!謝謝! – Kelketek 2012-03-05 20:11:51

0

您可以通過當地人這是個本地字典做符號表:

locals()["notify"]() 

或雖然全局它返回一個字典,全局符號表中:

globals()["notify"]() 

你可以給論點太例如: -

locals()["notify"]("Hello, world!") 

globals()["notify"]("Hello, world!") 
+0

我可以創建自己的符號表嗎?我不希望用戶能夠運行任何命令。 – Kelketek 2012-03-05 19:32:29

+1

'locals()'和'globals()'返回字典,所以你可以改爲自己創建。 – strcat 2012-03-05 19:36:08

+0

是@strcat是正確的。您可以使用此接口:http://docs.python.org/library/symtable.html#module-symtable 來檢查這些符號表。 – 2012-03-05 19:41:12

0

喜歡的東西:

import re 
class LangLib(object): 
    pattern = re.compile(r'"(.*?)" (.*)') 
    def run_line(self, line): 
     arg, command = re.match(LangLib.pattern, line).groups() 
     return getattr(self, command)(arg) 
    def notify(self, arg): 
     print arg 

然後你的引擎代碼如下:

parser = LangLib() 
for line in program_lines: 
    parser.run_line(line) 
0

如果你有一個名爲dictcommands映射名稱的功能,你可以做這樣的:

def my_notify_function(): 
    print(stack.pop) 

commands = {'notify': my_notify_function, ...} 

for item in program: 
    if item in commands: 
     commands[item]() 
    else: 
     stack.push(item) 
0

創建函數的名稱和一些標籤的字典。

我已經嘗試過好幾次了,它工作得很好。

相關問題