1

optparseを使用して引数を受け入れるほとんどのpythonicの方法に対する受け入れられた回答で説明されているように、文字列に対して操作を実行する関数を備えたプログラムがあります。プログラムはargparseを使用して、文字列がそのまま提供されているかファイルで提供されているかを確認し、必要に応じて入力をマッサージして関数に渡します。

ここで、関数のより高度なバージョンでプログラムを拡張したいのですが、スクリプトで2つの関数のうちの1つを実行するためにargparseを使用する場合のように、比較のために基本バージョンを残しておきます。私の状況が異なると思うのは、呼び出される関数に関係なく、既存の入力フラグも渡すオプションが必要なことです。

パーサーに新しい引数を追加し、そのフラグをチェックするif / else内に以前のコードをネストするだけでは、機能しません。引数の数が間違っていると文句を言います。私はサブコマンドを知っていますが、argparseはまだかなり新しいので、それは私が望むものにはやり過ぎのようですが、そうではないかもしれません。

tl; dr:2つの関数の1つと2つの入力タイプの1つを選択する必要があります。両方の入力タイプが両方の関数に適用されます。助けてくれてありがとう!

コードを追加するために編集:

p = argparse.ArgumentParser(description="program.py")
p.add_argument("-e", dest='extended')   #The new flag causing the trouble
p.add_argument("-s", dest="string")
p.add_argument("-f", dest="infile")

args = p.parse_args()

if args.extended:
    if args.infile:
        with open(args.infile,'r') as f:
            for line in enumerate(f.readlines()):
                print 'Input: ', line[1],    
                output = funcExtended(line[1])  #new and improved function
                print 'Extended output: ', output
    elif args.string:
        output = funcExtended(args.string)
        print output
    else:  #my future default option to grab strings from a database
        print 'This will soon work: extended'
else:   #I fully realize that I shouldn't have to essentially copy and paste here
    if args.infile:
        with open(args.infile,'r') as f:
            for line in enumerate(f.readlines()):
                print 'Input: ', line[1],    
                output = funcBasic(line[1])  #old and tired function
                print 'Basic output: ', output
    elif args.string:
        output = funcBasic(args.string)
        print output
    else:   #my future default option to grab strings from a database
        print 'This will soon work: basic'

これはコマンドラインユーティリティです。発行

$ python program.py -s 'string'

以前と同様に、適切にフォーマットされた文字列を返します。しかし、発行

$ python program.py -s 'string' -e

戻り値

program.py: error: argument -e: expected one argument

ふぅ。助けてくれる人にもう一度感謝します!

4

1 に答える 1

4

extended引数をブールフラグに変更した場合

p.add_argument("-e", dest='extended', action="store_true")

それはもはや引数を期待しません。次に、次のコマンドでスクリプトを呼び出すことができます。

$ python program.py -e -s 'string'

最後に、ボーナスとして、コードの冗長性を減らすためのいくつかのアイデアがあります。

import argparse

def funcExtended(line):
   return " ".join(line)

def funcBasic(line):
    return line.upper()

p = argparse.ArgumentParser(description="program.py")
p.add_argument("-e", "--extended", dest="func", action="store_const", const=funcExtended, default=funcBasic)
p.add_argument("-s", "--string")
p.add_argument("-f", "--infile")

args = p.parse_args()

def readlines(args):
    if args.infile:
        with open(args.infile,'r') as f:
            for line in f:
                yield line.rstrip("\n")
    elif args.string:
        yield args.string
    else:  #my future default option to grab strings from a database
        print 'This will soon work: extended'

for line in readlines(args):
    print 'Input: ', line
    output = args.func(line)
    print "Output: ", output
于 2012-09-14T07:33:45.117 に答える