2011-11-23 66 views
12

比方說,我有一個腳本,在文件上做一些工作。它會在命令行中使用該文件的名稱,但如果未提供該文件,則默認爲已知文件名(例如content.txt)。與python的​​,我使用以下內容:用argparse指定默認文件名,但不打開它們--help?

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 
# do some work on args.content, which is a file-like object 

這很好。唯一的問題是,如果我運行python myscript --help,如果文件不存在(我認爲有意義),則獲得ArgumentError,並且不顯示幫助文本。我寧願它不嘗試打開文件,如果用戶只想要--help。有沒有辦法做到這一點?我知道我可以將參數設置爲一個字符串,並在以後自己打開文件(我一直這樣做),但是​​可以很方便地處理它。

+0

嗯,它看起來像你必須在這裏做一個決定。您可以使默認文件可用(由於它是「默認」),或者只是自己打開文件,就像您建議的那樣。或者,您可以使用stdin作爲默認值,但是您將無法指定默認文件名,如果您不想填充該文件,這可能不是一個錯誤的選項。 –

回答

9

望着argparse代碼,我看到:

  • ArgumentParser.parse_args電話parse_known_args,並確保沒有被解析任何未決的爭論。
  • ArgumentParser.parse_known_args套的默認值,並調用ArgumentParser._parse_known_args

因此,解決方法是使用直接ArgumentParser._parse_known_args檢測-h和,之後,用ArgumentParser.parse_args如常。

import sys, argparse 
parser = argparse.ArgumentParser(description='my illustrative example', argument_default=argparse.SUPPRESS) 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=argparse.FileType('r'), 
        help='file to process (defaults to content.txt)') 
parser._parse_known_args(sys.argv[1:], argparse.Namespace()) 
args = parser.parse_args() 

注意ArgumentParser._parse_known_args需要幾個參數:在命令行和命名空間中的參數。

當然,我不會推薦這種方法,因爲它利用了內部的​​實現,這在未來可能會改變。但是,我不覺得它太雜亂,所以如果您認爲維護風險能夠得到回報,您仍然可能會使用它。

+0

看起來這並不是一個很好的解決方案,但是這將用於一次性腳本。謝謝! –

1

也許你可以在add_argument調用,檢查文件是否存在,如果它和None(或別的東西),否則返回一個文件句柄定義自己typeaction

儘管如此,這還是需要你自己寫一些代碼,但是如果不能總是使用默認值,那麼你可能不得不遲早做一些檢查。像曼尼D認爲你可能想重新考慮你的默認值。

12

你可以繼承argparse.FileType

import argparse 
import warnings 

class ForgivingFileType(argparse.FileType): 
    def __call__(self, string): 
     try: 
      super(ForgivingFileType,self).__call__(string) 
     except IOError as err: 
      warnings.warn(err) 

parser = argparse.ArgumentParser(description='my illustrative example') 
parser.add_argument('--content', metavar='file', 
        default='content.txt', type=ForgivingFileType('r'), 
        help='file to process (defaults to content.txt)') 
args = parser.parse_args() 

這工作,而無需觸摸像ArgumentParser._parse_known_args私有方法。

2

使用標準輸入默認:

parser.add_argument('file', default='-', nargs='?', type=argparse.FileType('r')) 
相關問題