2013-06-12 45 views
1

請參閱here以瞭解有關Python中各種選項和arg解析選擇優點的相關討論。Python argparse:如何獲得簡單的解析行爲?

我正在製作一個diff腳本,用Python的difflib的輸出完成整潔的事情,其中​​涉及的部分內容是處理它可以調用的不同方式。例如,Git會發送7個參數(第二個和第五個是您想要區分的文件)到您配置的diff程序中,並且大多數不同也會接受輸入爲兩個文件參數。有趣的是,git的difftool--extcmd=標誌調用你指定的差異只有兩個參數。

因此,使用OptionParser來做這件事非常容易,因爲它只是給你一個參數列表,我可以抓住第二個和第五個,並將它們發送到fileinput

我沒有注意到pydoc上的大旗幟,說它已經過時,所以我在看​​。

根本不清楚,如果甚至可以配置​​讓程序接受一系列位置參數而沒有「啓動它」的選項。這是我所需要的,因爲我無法改變方式,例如Git會調用不同的。

無論如何,我最終做了一些非常微不足道的操縱sys.argv,這畢竟是我應該在這種特殊情況下開始做的事情。

if len(sys.argv) == 8: 
     # assume this was passed to git; we can of course do 
     # some parsing to check if we got valid git style args 
     args = [sys.argv[2], sys.argv[5]] 
elif len(sys.argv) == 3: 
     args = sys.argv[:1] 
else: 
     sys.exit("Not a valid number of args (2 or 7) to this diff program") 
print "Files: " + ' '.join(args) 

一個人怎麼可能會使用argparse來實現,簡單地試圖打開並閱讀所有它的參數的程序?

推理原因是​​棄用parseopt它必須有可能複製其所有功能(在合理範圍內)。

+0

請發佈您用於操作'sys.argv'的代碼。那麼也許我們可以建議如何用'argparse'來做同樣的事情。 – unutbu

+0

@unutbu編輯。 –

回答

0

你可以定義這個custom Action,雖然它真的並不比後期處理args自己,除非你有不同許多此類參數需要執行此操作:

import argparse 

class TwoOrSeven(argparse.Action): 
    def __call__(self, parser, namespace, values, option_string=None): 
     if len(values) not in (2,7): 
      raise argparse.ArgumentTypeError('Not a valid number of args (2 or 7)') 
     try: 
      values = values[2], values[5] 
     except IndexError: 
      values = values[0] 
     setattr(namespace, self.dest, values) 
parser = argparse.ArgumentParser() 
parser.add_argument('args', metavar='arg', action=TwoOrSeven, nargs='+', 
    help='Must be supplied 2 or 7 arguments') 

args = parser.parse_args('1 2 3 4 5 6 7'.split()) 
print(args) 
# Namespace(args=('3', '6')) 
args = parser.parse_args('1 2'.split()) 
print(args) 
# Namespace(args='1') 
args = parser.parse_args('1 2 3 4 5 6'.split()) 
# argparse.ArgumentTypeError: Not a valid number of args (2 or 7) 
1

只需添加一個在它前面沒有破折號的參數即可。

import argparse 
parser = argparse.ArgumentParser() 
# You can change nargs to '+' for at least one argument 
parser.add_argument('positional', nargs=2) # Positionals have no dashes 
parser.add_argument('second_positional', nargs=1) 
parser.add_arguemnt('--optional', '-o') # Optionals have dashes 
args = parser.parse_args() 

print args['positional'] # Your first two positional arguments 
print args['second_positional'] # Second set 
print args['optional'] # An optional argument 
+0

我怎樣才能讓它接受* * 2或7個參數,但如果你用5個參數調用它,就會拒絕? –

+0

我會使用可變數量的參數('nargs ='+''),如果len(args ['positions'])不在(2,7)'中,則失敗。 – SethMMorton

1

我剛纔提出這個例子,採取了零個或多個位置參數:

import argparse 

parser = argparse.ArgumentParser() 
parser.add_argument('args', metavar='arg', type=str, nargs='*', 
    help='zero or more positional arguments') 

args = parser.parse_args() 
print args.arguments 
+0

啊,好的。我想我必須在args.arguments上做邏輯,看看它是否有正確的計數。 –

+0

如果你需要做的事情,例如有2或7,但沒有別的,這似乎是要走的路。 –