1

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

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

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

感谢所有建议!

更新:我的程序的重点是生成对象并将它们通过任意数量的过滤器(可能是不纯/有效的操作),这些过滤器可能会或可能不会再次输出对象,甚至可能输出另一种类型的对象。总体思路显然是从 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'
4

2 回答 2

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 是不可能的,只有-aor --argument。这对你来说可能已经是一个交易破坏者了,我不确定......

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

optparsegetopt而言,我很确定你可以用它们做的任何事情,你都可以用 argparse 做,这就是为什么我把它们排除在讨论之外的原因。

于 2012-04-28T17:37:13.950 回答
1

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

于 2012-04-28T14:30:56.330 回答