Python:解析命令行
我正在用python编写一个CLI应用程序,它通过一种相当复杂的命令行语言使用。这个想法与find1非常相似,find1可以说具有相同的属性 目前,解析器完全是使用手工制作的EBNF描述语言手工编写的。问题是这种语言使用起来非常笨拙,因为我必须以python结构编写所有内容。我还觉得我的程序仍然因为解析而过于臃肿 是否有易于使用的库,以及作为字符串/文档输入的真实描述语言,用于命令行解析?在语法树中,我想直接将每个项映射到一个类实例。当然,我不想要标记器,或者至少标记器必须直接从命令行参数映射到标记 谢谢你的建议 更新:我的程序的全部要点是生成对象,并通过任意数量的过滤器传递它们,这些过滤器可能是不完整/有效的操作,这些操作可能会再次输出对象,也可能不会再次输出对象,甚至可能输出另一种类型的对象。总体思路显然是从find1中收集的。命令行示例如下:Python:解析命令行,python,parsing,Python,Parsing,我正在用python编写一个CLI应用程序,它通过一种相当复杂的命令行语言使用。这个想法与find1非常相似,find1可以说具有相同的属性 目前,解析器完全是使用手工制作的EBNF描述语言手工编写的。问题是这种语言使用起来非常笨拙,因为我必须以python结构编写所有内容。我还觉得我的程序仍然因为解析而过于臃肿 是否有易于使用的库,以及作为字符串/文档输入的真实描述语言,用于命令行解析?在语法树中,我想直接将每个项映射到一个类实例。当然,我不想要标记器,或者至少标记器必须直接从命令行参数映射到
~/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:谢谢,说得好,我会更新我的帖子,希望得到更好的答案,而不仅仅是反问:非常感谢你的努力。这意味着我可能会继续使用我的手工解决方案。非常感谢您的努力。这意味着我可能会继续使用手工制作的解决方案。