2010-05-26 69 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的另一种方式。

我将被隔空击到我的壳

这将是不知不觉慢,如果没有找到该命令,但不足以物质的效率。如果做了基准测试,只有成千上万的条目,你才会注意到它。

相关问题