Python:解析命令行

时间:2012-04-28 13:57:54

标签: python parsing

我正在python中编写一个CLI应用程序,它是通过一种相当复杂的命令行语言来使用的。这个想法非常类似于find(1),它可以说具有相同的属性。

目前,解析器完全是使用手工制作的EBNF描述语言手写的。问题是这种语言使用起来很尴尬,因为我必须把所有东西都写成python结构。我也觉得由于解析,我的程序仍然过于膨胀。

是否有任何易于使用的lib,以及用于命令行解析的真正描述语言(输入为字符串/文档)?从语法树,我想直接将每个项映射到类实例。当然,我不想要一个标记化器,或者至少令牌化器必须直接从命令行参数映射到标记。

感谢所有建议!

UPDATE :我的程序的重点是生成对象并将它们传递给可能会或可能不会再次输出对象的任意数量的过滤器(可能是不可行/有效的操作),甚至可能输出另一种类型的对象。一般的想法显然是从find(1)中收集的。示例命令行将是:

~/picdb.py -sqlselect 'select * from pics where dirname like "testdir%"' -tagged JoSo  -updateFromFile [ -resx +300 -or -resX +200 -resY +500 ] -printfXml '<jpegfile><src>%fp</src><DateTimeOriginal>%ed</DateTimeOriginal><Manufacturer>%eM</Manufacturer><Model>%em</Model></jpegfile>%NL'

2 个答案:

答案 0 :(得分:3)

这是一个非常棘手的问题......您可以非常轻松地使用argparse将操作绑定到命令行参数(例如,创建一个类,对先前创建的类进行操作......)。这是一个愚蠢的例子......(参数--foo创建一个对象,参数--bar修改由--foo创建的对象)。

from argparse import ArgumentParser,Action

class Foo(object):
    def __init__(self,*args):
        self.args=args
    def __str__(self):
        return str(self.args)

class FooAction(Action):
    def __call__(self,parser,namespace,values,option_string=None):
        setattr(namespace,self.dest,Foo(*values))  #Add Foo to the options...
class BarAction(Action):
    def __call__(self,parser,namespace,values,option_string=None):
        FooObj=getattr(namespace,'foo')  #raises an error if foo isn't in namespace...
                                         #In this way, BarAction is like a filter on the
                                         #object created by foo.
        FooObj.args=tuple(list(FooObj.args)+list(values)) #append to the list of args.

parser=ArgumentParser()
parser.add_argument('--foo',nargs='*',action=FooAction,help="Foo!")
parser.add_argument('--bar',nargs='*',action=BarAction,help="Bar! : Must be used after --foo")

namespace=parser.parse_args("--foo Hello World --bar Nice Day".split())
print (namespace)
print (namespace.foo)

但是,这与您的情况略有不同,因为-argument对于argparse来说是不可能的,只有-a--argument。这对你来说可能已经成为一个破坏者,我不确定......

下一个难点是处理括号...... []。如果你可以将它们视为不同命令行选项的参数,那么你可能没问题......你可能能够设置第二个解析器来解析内部部分 - 但我以前从未尝试过类似的东西。 (如果其他人对如何处理括号有任何想法,我会非常有兴趣听到它们。)

optparsegetopt而言,我很确定你可以用它们做什么,你可以用argparse,这就是为什么我把它们排除在外讨论

答案 1 :(得分:1)

你可以尝试至少三个模块; argparseoptparse(在2.7中已弃用)和getopt。请参阅Python标准库手册的第15章。