2012-07-12 3 views
12

私のpythonスクリプトでは、オプションの入力パラメータしか使用できません。別のオプションのパラメータが指定されている場合はです。例:python、argparse:別のパラメータが指定されている場合に入力パラメータを有効にします

$ python myScript.py --parameter1 value1 
$ python myScript.py --parameter1 value1 --parameter2 value2 

ではなく、私はargparseでこれを行うにはどうすればよい

$ python myScript.py --parameter2 value2 

ありがとうございます!

+1

あなたは 'myScript.py --parameter2値2 --parameter1 value1'場合に発生することが何をしたいですか?あなたがそれを通過させたい場合、対処するのは非常に難しいケースです。 – mgilson

+1

http://bugs.python.org/issue11588は 'mutually_inclusive_group'機能のバグリクエストです。この場合、 '--parameter1'は' --parameter2'なしで実行できるので、これはうまくいきません。この問題や関連する制約をどのように実装できるかについてのアイデアがあれば、その問題に貢献してください。 – hpaulj

答えて

10

カスタムアクションを使用します。

import argparse 

foo_default=None  

class BarAction(argparse.Action): 
    def __call__(self,parser,namespace,values,option_string=None): 
     didfoo=getattr(namespace,'foo',foo_default) 
     if(didfoo == foo_default): 
      parser.error("foo before bar!") 
     else: 
      setattr(namespace,self.dest,values) 

parser=argparse.ArgumentParser() 
parser.add_argument('--foo',default=foo_default) 
parser.add_argument('--bar',action=BarAction,help="Only use this if --foo is set") 

#testing. 
print parser.parse_args('--foo baz'.split()) 
print parser.parse_args('--foo baz --bar cat'.split()) 
print parser.parse_args('--bar dog'.split()) 

これもあなたがargparseの一部の文書化されていない動作に依存してOKなら仕方を維持するために、少し簡単に行うことができますで

import argparse 

parser=argparse.ArgumentParser() 
first_action=parser.add_argument('--foo',dest='cat',default=None) 

class BarAction(argparse.Action): 
    def __call__(self,parser,namespace,values,option_string=None): 
     didfoo=getattr(namespace,first_action.dest,first_action.default) 
     if(didfoo == first_action.default): 
      parser.error("foo before bar!") 
     else: 
      setattr(namespace,self.dest,values) 

parser.add_argument('--bar',action=BarAction, 
        help="Only use this if --foo is set") 

#testing. 
print parser.parse_args('--foo baz'.split()) 
print parser.parse_args('--foo baz --bar cat'.split()) 
print parser.parse_args('--bar dog'.split()) 

この例では、fooのデフォルトを取得し、add_argumentによって返されたアクションオブジェクトからの宛先を取得します(add_argumentの戻り値はどこにも記載されていません)。これはまだ少し脆いです(たとえば、--foo引数にtype=キーワードを指定する場合)。

最後に、解析する前にsys.argvをチェックすることができます。

import sys 
if ("--parameter2" in sys.argv) and ("--parameter1" not in sys.argv): 
    parser.error("parameter1 must be given if parameter2 is given") 

--parameter1--p1によってトリガすることができますが、あなたのアイデアを得る場合、これはもう少しトリッキー取得します。次に使用することができます

if (set(sys.argv).intersection(('--p2',...)) and 
    not set(sys.argv).intersection(('--p1',...))) 

ここでの利点は、特別な注文を必要としないことです。 (--p2はコマンドラインで--p1に従う必要はありません)。また、前と同じように、option_strings属性を使用して特定のアクションをトリガーするコマンド文字列のリストを取得することができます。これはparser.add_argument(...)によって返されます。例えば

import argparse 
import sys 
parser=argparse.ArgumentParser() 
action1=parser.add_argument('--foo') 
action2=parser.add_argument('--bar', 
          help="Only use this if --foo is set") 

argv=set(sys.argv) 
if ((argv & set(action2.option_strings)) and 
     not (argv & set(action1.option_strings))): 
       #^ set intersection 
    parser.error(' or '.join(action1.option_strings)+ 
        ' must be given with '+ 
        ' or '.join(action2.option_strings)) 
2

ひとつのアイデアは、手動でparser.parse_args()を呼び出すの出力をチェックし、例外を発生させるか、そうでなければ--parameter2が使用されるが--parameter1がないと失敗するだろう。

また--parameter1は、名前空間内に存在する場合--parameter2チェックする(ビットをスクロールダウン)custom actionを設定してみてください。

最後にsubparsersを試すことができますが、--parameter1の値を指定できるかどうかはわかりません。

2

parse_known_args()を使用して、をパーサーに追加する前に--parameter1が指定されているかどうかを確認できます。

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('--parameter1', dest='p1') 
args = parser.parse_known_args()[0] 
if args.p1: 
    parser.add_argument('--parameter2', dest='p2') 
args = parser.parse_args() 

if args.p1: 
    print args.p1 
if args.p2: 
    print args.p2 

結果:

$ python myScript.py --parameter1 a 
a 
$ python myScript.py --parameter1 a --parameter2 b 
a 
b 
$ python myScript.py --parameter2 b 
usage: myScript.py [-h] [--parameter1 P1] 
myScript.py: error: unrecognized arguments: --parameter2 b 
+2

'--help'は不正確になります。 – pmav99

関連する問題