Python:解析命令行

Python:解析命令行,python,parsing,Python,Parsing,我正在用python编写一个CLI应用程序,它通过一种相当复杂的命令行语言使用。这个想法与find1非常相似,find1可以说具有相同的属性 目前,解析器完全是使用手工制作的EBNF描述语言手工编写的。问题是这种语言使用起来非常笨拙,因为我必须以python结构编写所有内容。我还觉得我的程序仍然因为解析而过于臃肿 是否有易于使用的库,以及作为字符串/文档输入的真实描述语言,用于命令行解析?在语法树中,我想直接将每个项映射到一个类实例。当然,我不想要标记器,或者至少标记器必须直接从命令行参数映射到

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

目前,解析器完全是使用手工制作的EBNF描述语言手工编写的。问题是这种语言使用起来非常笨拙,因为我必须以python结构编写所有内容。我还觉得我的程序仍然因为解析而过于臃肿

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

谢谢你的建议

更新:我的程序的全部要点是生成对象,并通过任意数量的过滤器传递它们,这些过滤器可能是不完整/有效的操作,这些操作可能会再次输出对象,也可能不会再次输出对象,甚至可能输出另一种类型的对象。总体思路显然是从find1中收集的。命令行示例如下:

~/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'

您至少可以尝试三个模块;argparse、optparse在2.7和getopt中不推荐使用。请参阅Python标准库手册的第15章。

您至少可以尝试三个模块;argparse、optparse在2.7和getopt中不推荐使用。请参阅Python标准库手册的第15章。

这是一个非常棘手的问题…您可以使用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)
然而,这与您的有一点不同,在argparse中-argument实际上是不可能的,只有-a或-argument。那对你来说可能已经是个破坏者了,我不确定

下一个困难是处理括号。。。[和]。如果您可以将这些作为另一个命令行选项的参数来处理,那么您可能还可以…您可以设置第二个解析器来解析内部部分-但是我以前从未尝试过类似的方法。。。如果其他人对如何处理括号有任何想法,我将非常有兴趣听取他们的意见


就optparse和getopt而言,我很确定你可以用它们做任何事情,你可以用argparse做任何事情,这就是为什么我将它们排除在讨论之外。

这是一个非常棘手的问题…你可以很容易地用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)
然而,这与您的有一点不同,在argparse中-argument实际上是不可能的,只有-a或-argument。那对你来说可能已经是个破坏者了,我不确定

下一个困难是处理括号。。。[和]。如果您可以将这些作为另一个命令行选项的参数来处理,那么您可能还可以…您可以设置第二个解析器来解析内部部分-但是我以前从未尝试过类似的方法。。。如果其他人对如何处理括号有任何想法,我将非常有兴趣听取他们的意见


就optparse和getopt而言,我很确定你可以用它们做任何事情,你也可以用argparse做任何事情,这就是为什么我将它们排除在讨论之外。

python 2.7+是否适合你的需要?除了@Aufwind的评论之外,你不需要用python 2.7或更新的版本来使用argparse。它适用于较旧版本的python-您只需自行安装,而不是包含在标准库中。我认为,如果您描述了命令行或至少给出了一两个示例,我们可能会看到这是否是argparse/optparse的候选项…@mgilson:谢谢,说得好,我将更新我的帖子,希望得到更好的答案,而不仅仅是反问:python 2.7+是否适合您的需要?除了@Aufwind的评论之外,您不需要为用户argparse提供python 2.7或更新版本。它适用于较旧版本的python-您只需自行安装,而不是包含在标准库中。我认为,如果您描述了命令行或至少给出了一两个示例,我们可能会看到这是否是argparse/optparse的候选项…@mgilson:谢谢,说得好,我会更新我的帖子,希望得到更好的答案,而不仅仅是反问:非常感谢你的努力。这意味着我可能会继续使用我的手工解决方案。非常感谢您的努力。这意味着我可能会继续使用手工制作的解决方案。