2012-04-19 6 views
3

cmdモジュールを使用して簡単なPythonスクリプトを作成しています。このモジュールを使用すると、基本的なURLクエリ文字列形式のパラメータが続くテキストコマンドを入力できます。プロンプトがcmdを使ってPython cmdモジュール - 行からの値の解析

commandname foo=bar&baz=brack

のようなもので答えられるだろう、私は引数lineはすべてdo_*メソッドに渡される方法に影響を与えるために上書きするためにどの方法を見つけるように見えることはできません。私はこれらの値にurlparse.parse_qsを実行したいと思います。そして、do_*の方法のたびにこれを呼び出すのは不思議です。

が分割されて解釈される前に、precmdメソッドが行全体を取得するため、これは私の目的のためには機能しません。私はまたこのようなクラスの中にデコレータを配置する方法にひどく慣れておらず、スコープを破ることなくそれを引き出すことができませんでした。

は基本的には、cmdのためのPythonのドキュメントは、次の

が繰り返し彼らにの 残りを渡して、入力を受け付け、プロンプトを発行するアクションメソッドへの初期 オフ接頭受信した入力、およびディスパッチを解析言います引数としての行

私はむしろ、すべての関数でそれらを解釈するよりも、line引数としてメンバ関数にオフ辞書生成する「行の残りの部分」と手に追加の処理を行います方法を作りたいです。

ありがとうございます!

答えて

3

次の簡単な例に示すように、onecmd()メソッドをオーバーライドする可能性があります。 onecmd()メソッドには、基本的に元のcmd.pyのもののコピーがありますが、引数を関数に渡す前にurlparse.parse_qs()への呼び出しを追加します。

import cmd 
import urlparse 

class myCmd(cmd.Cmd): 
    def onecmd(self, line): 
     """Mostly ripped from Python's cmd.py""" 
     cmd, arg, line = self.parseline(line) 
     arg = urlparse.parse_qs(arg) # <- added line 
     if not line: 
      return self.emptyline() 
     if cmd is None: 
      return self.default(line) 
     self.lastcmd = line 
     if cmd == '': 
      return self.default(line) 
     else: 
      try: 
       func = getattr(self, 'do_' + cmd) 
      except AttributeError: 
       return self.default(line) 
      return func(arg) 

    def do_foo(self, arg) 
     print arg 

my_cmd = myCmd() 
my_cmd.cmdloop() 

出力例:

(Cmd) foo 
{} 
(Cmd) foo a b c 
{} 
(Cmd) foo a=b&c=d 
{'a': ['b'], 'c': ['d']} 

は、これはあなたが達成しようとしているものですか?

ここ cmd.Cmdサブクラスを変更し、基本的には、そのクラスのすべてのdo_* 方法にデコレータ関数を適用するために、クラスのデコレータを使用する別の潜在的なソリューションです:私はすぐに一緒にこれを石畳と、それが表示されます

import cmd 
import urlparse 
import types 

# function decorator to add parse_qs to individual functions 
def parse_qs_f(f): 
    def f2(self, arg): 
     return f(self, urlparse.parse_qs(arg)) 
    return f2 

# class decorator to iterate over all attributes of a class and apply 
# the parse_qs_f decorator to all do_* methods 
def parse_qs(cls): 
    for attr_name in dir(cls): 
     attr = getattr(cls, attr_name) 
     if attr_name.startswith('do_') and type(attr) == types.MethodType: 
      setattr(cls, attr_name, parse_qs_f(attr)) 
    return cls 

@parse_qs 
class myCmd(cmd.Cmd): 
    def do_foo(self, args): 
     print args 

my_cmd = myCmd() 
my_cmd.cmdloop() 

は、しかし、私は の落とし穴に関する提案や、この解決策をどのように改善できるかについては公開しています。

関連する問題