10

シェルのような環境を作成しています。ユーザー入力を処理する私の元の方法は、関数がPythonのファーストクラスオブジェクトであるという事実を利用して、さまざまなクラスのメソッドにコマンド(文字列)をマッピングする辞書を使用することでした。

柔軟性のために(主にコマンドの解析のために)、getattr(command)を使用するようにセットアップを変更し、必要なメソッドを取得して、パーサーの最後に引数を渡すことを考えています。このアプローチのもう1つの利点は、新しいメソッド/コマンドを追加するたびに(現在静的に実装されている)コマンドディクショナリを更新する必要がないことです。

私の質問は2つあります。まず、getattrにはevalと同じ問題がありますか?第二に、シェルの効率に打撃を与えるでしょうか?私が持っているメソッド/コマンドの数は重要ですか?現在、30個のコマンドを調べていますが、最終的には2倍になる可能性があります。

4

2 に答える 2

27

直接属性アクセスとgetattr()の使用の違いは、かなり無視できるはずです。disPythonのモジュールを使用して2つのアプローチを比較することにより、2つのバージョンのバイトコードの違いを知ることができます。

>>> 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がコマンドラインシェルを実行する方法と非常によく似たシェルを開発しているように聞こえます。コマンド名を次のようなオブジェクト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を参照してください。

于 2010-05-26T02:07:55.203 に答える
9

getattrにはevalと同じ問題がありますか?

いいえ-コードを使用eval()すると、保守が非常に面倒になり、深刻なセキュリティ問題が発生する可能性があります。呼び出しgetattr(x, "foo")は、を書くためのもう1つの方法x.fooです。

シェルの効率に打撃を与えますか

コマンドが見つからない場合は、知覚できないほど遅くなりますが、問題になるほどで​​はありません。何万ものエントリがあるベンチマークを実行している場合にのみ気付くでしょう。

于 2010-05-26T00:46:16.133 に答える