2012-04-19 61 views
3

我正在使用cmd模块的一个快速python脚本,它允许用户输入文本命令,然后输入基本url查询字符串格式的参数。该提示将东西来回答类似Python的cmd模块 - 解析线的值

commandname foo=bar&baz=brack

使用CMD,我似乎无法找到重写影响的说法line被传递给所有的do_*方法的方法哪一种方法。我想对这些值运行urlparse.parse_qs,并在每个do_*方法中调用此行看起来很笨拙。

precmd方法得到整条线,在commandname被拆分和解释之前,所以这不适用于我的目的。我也不是很熟悉如何在类中放置一个装饰器,并且无法在不破坏范围的情况下将其修改。

基本上,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() 

我很快就拼凑了一起,它似乎按预期工作,但是,我对 有任何问题的建议,或者如何改进此解决方案。