2010-05-26 50 views
7

我正在創建一個類似shell的環境。我處理用戶輸入的原始方法是使用字典映射命令(字符串)各種類的方法,利用這個事實,即函數是python中的第一類對象。爲了靈活性(主要是解析命令),我正在考慮改變我的設置,以便使用getattr(command)來獲取我需要的方法,然後在我的結尾處傳遞參數給它解析器。這種方法的另一個優點是不必每次添加新的方法/命令時更新我的​​(當前靜態實現的)命令字典。廣泛使用python的getattr是不好的做法嗎?

我的問題是兩倍。首先,getattr與eval有相同的問題嗎?其次,我會受到我的外殼效率的影響嗎?這有關係我有多少方法/命令?我目前正在查看30個命令,最終可能會翻一番。

+1

如果你還沒有看過pyparsing http://pyparsing.wikispaces.com/你真的應該,有__NO__真正的理由編寫你自己的解析器在python中的任何東西。 – 2010-05-26 02:11:49

+2

模糊,我很確定我能想到一個,這就是我爲了學習目的而做的。在開始這個當前的項目之前,我不明白函數是第一類對象的含義。儘管如此,我很欣賞這個參考。我會研究它。 – Wilduck 2010-05-27 04:20:52

回答

20

直接屬性訪問和使用getattr()之間的區別應該可以忽略不計。您可以使用Python的dis模塊的兩種方法比較告訴兩個版本字節碼的區別:

>>> import dis 
>>> dis.dis(lambda x: x.foo) 
    1   0 LOAD_FAST    0 (x) 
       3 LOAD_ATTR    0 (foo) 
       6 RETURN_VALUE   
>>> dis.dis(lambda x: getattr(x, 'foo')) 
    1   0 LOAD_GLOBAL    0 (getattr) 
       3 LOAD_FAST    0 (x) 
       6 LOAD_CONST    0 ('foo') 
       9 CALL_FUNCTION   2 
      12 RETURN_VALUE 

它,然而,聽起來就像你正在開發一個殼,這是非常相似的如何Python庫cmd執行命令行shell。 cmd,您可以創建一個命令名匹配,像這樣一個cmd.Cmd對象上定義的函數執行命令彈:

import cmd 

class EchoCmd(cmd.Cmd): 
    """Simple command processor example.""" 

    def do_echo(self, line): 
     print line 

    def do_EOF(self, line): 
     return True 

if __name__ == '__main__': 
    EchoCmd().cmdloop() 

您可以在任何文檔閱讀更多有關模塊,或在http://www.doughellmann.com/PyMOTW/cmd/index.html

+1

+1「dis check」。 – EOL 2010-05-26 07:25:45

+0

感謝您的回覆。正如我在上面的評論中,我真的爲了學習目的而編寫這個shell。在未來,如果我實際上需要爲某種生產目的編寫一個shell,我將使用cmd。我不知道關於dis,但感謝參考。 – Wilduck 2010-05-27 04:22:52

6

getattr是否與eval具有相同的問題?

沒有 - 使用eval()的代碼非常惱人的維護,並可能有嚴重的安全問題。撥打getattr(x, "foo")只是編寫x.foo的另一種方式。

我將被隔空擊到我的殼

這將是不知不覺慢,如果沒有找到該命令,但不足以物質的效率。如果做了基準測試,只有成千上萬的條目,你纔會注意到它。

相關問題