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)

ただし、これはargparse、only 、または-argumentで実際には不可能であるという点で、あなたのものとは少し異なります。それはすでにあなたにとって取引のブレーカーかもしれません、私にはわかりません... -a--argument

次の難しさは角かっこを扱うことです...[そして]。それらを別のコマンドラインオプションへの引数として扱うことができれば、大丈夫かもしれません...内部部分を解析するために2番目のパーサーを設定できるかもしれません-しかし、私はこれまでそのようなことを試したことがありません。 。(他の誰かがブラケットの扱い方について何かアイデアを持っているなら、私はそれらを聞くことに非常に興味があります)。

optparseとに関する限りgetopt、私はあなたがそれらでできることは何でも、あなたはargparseでできると確信しています。それが、私がそれらを議論から除外した理由です。

于 2012-04-28T17:37:13.950 に答える
1

試すことができるモジュールは少なくとも3つあります。argparseoptparse(2.7で非推奨)およびgetopt。Python標準ライブラリマニュアルの第15章を参照してください。

于 2012-04-28T14:30:56.330 に答える