2009-12-10 7 views
14

これまでのところoptparseを使用していましたが、設定ファイルから引数を読み込む機能を追加したいと考えています。ファイルを使用してオプティマイズの引数を格納する

私が考えることができる最高のものは、引数がハードコードされたラッパーバッチスクリプトです。

これを行う最もエレガントな方法は何ですか?

答えて

22

私は、configファイルを使用してのS.Lottの考えに同意するが、私はそれを解析するために、内蔵ConfigParser(のConfigParser 3.0で)モジュールではなく、自家製のソリューションを使用してお勧めします。

ここには、ConfigParserとoptparseが実際に動作していることを示す簡単なスクリプトがあります。

import ConfigParser 
from optparse import OptionParser 

CONFIG_FILENAME = 'defaults.cfg' 

def main(): 
    config = ConfigParser.ConfigParser() 
    config.read(CONFIG_FILENAME) 

    parser = OptionParser() 
    parser.add_option("-l", 
         "--language", 
         dest="language", 
         help="The UI language", 
         default=config.get("Localization", "language")) 
    parser.add_option("-f", 
         "--flag", 
         dest="flag", 
         help="The country flag", 
         default=config.get("Localization", "flag")) 

    print parser.parse_args() 

if __name__ == "__main__": 
    main() 

出力: "parser.py --language=French "と

(<Values at 0x2182c88: {'flag': 'japan.png', 'language': 'Japanese'}>, []) 

実行します。

(<Values at 0x2215c60: {'flag': 'japan.png', 'language': 'French'}>, []) 

ヘルプが組み込まれている" parser.py --help" と ラン:

Usage: parser.py [options] 

Options: 
    -h, --help   show this help message and exit 
    -l LANGUAGE, --language=LANGUAGE 
         The UI language 
    -f FLAG, --flag=FLAG The country flag 

設定ファイル:

[Localization] 
language=Japanese 
flag=japan.png 
3

これは、set_defaultsの機能です。 http://docs.python.org/library/optparse.html#optparse.OptionParser.set_defaults

デフォルト値の辞書であるファイルを作成します。

{ 'arg1': 'this', 
'arg2': 'that' 
} 

次に辞書にテキストを変換し、set_defaultsの引数としてこの辞書を提供するために、それをevalし、このファイルを読み取ります。

evalが本当に心配な方は、このファイルにJSON(またはYAML)表記を使用してください。または、.INIファイルを作成してconfigparserを使用してデフォルト値を取得することもできます。

また、代入文とexecの簡単なリストを使用することもできます。

設定ファイル。

arg1 = 'this' 
arg2 = 'that' 

設定ファイルを読み込みます。

defaults= {} 
with open('defaults.py','r') as config 
    exec config in {}, defaults 
+0

上でコードを共有している - あなただけのマーシャリングを使用することができます。 –

+1

@Nick Bastin:EvalはEvilではなく、常にevalの使用を利用してアプリケーションをハッキングしようとしている社会的なエンドユーザーだけです。 –

+0

あなたの鎧の隙間を利用して攻撃者に指をぶつけても、隙間をなくすことも攻撃を止めることもできません。:) –

7

あなたはそのためargparseモジュールを使用することができます。

>>> open('args.txt', 'w').write('-f\nbar') 
>>> parser = argparse.ArgumentParser(fromfile_prefix_chars='@') 
>>> parser.add_argument('-f') 
>>> parser.parse_args(['-f', 'foo', '@args.txt']) 
Namespace(f='bar') 

それはSTDLIBに含まれている場合があります、pep 389を参照してください。

+4

PEP 389が承認され、 'argparse'はすでにPython 2.7の一部です。 – sorin

4

私は同様の問題を抱えていましたが、設定ファイルを引数として特定したいと思っていました。 S. Lottの答えに触発されて、私は次のコードを思いついた。

例端末セッション:

$ python defaultconf.py # use hard-coded defaults 
False 
$ python defaultconf.py --verbose # verbose on command line 
True 
$ python defaultconf.py --loadconfig blah # load config with 'verbose':True 
True 
$ python defaultconf.py --loadconfig blah --quiet # Override configured value 
False

コード:

#!/usr/bin/env python2.6 
import optparse 

def getParser(defaults): 
    """Create and return an OptionParser instance, with supplied defaults 
    """ 
    o = optparse.OptionParser() 
    o.set_defaults(**defaults) 
    o.add_option("--verbose", dest = "verbose", action="store_true") 
    o.add_option("--quiet", dest = "verbose", action="store_false") 

    o.add_option("--loadconfig", dest = "loadconfig") 

    return o 


def main(): 
    # Hard coded defaults (including non-command-line-argument options) 
    my_defaults = {'verbose': False, 'config_only_variable': 42} 

    # Initially parse arguments 
    opts, args = getParser(my_defaults).parse_args() 

    if opts.loadconfig is not None: 
     # Load config from disk, update the defaults dictionary, and reparse 
     # Could use ConfigParser, simplejson, yaml etc. 

     config_file_values = {'verbose': True} # the dict loaded from disk 

     my_defaults.update(config_file_values) 
     opts, args = getParser(my_defaults).parse_args() 

    print opts.verbose 

if __name__ == '__main__': 
    main() 

実用的な実装では、GitHubの上で見つけることができる:The defaults dictionarythe argument parserthe main function

+0

それは素晴らしいことです。 --helpの設定ファイルのデフォルト値も表示するように拡張しました: –

2

は、同じコマンドライン形式で引数を読みますファイルから@コマンドを使用して、元のパーサーを使用して解析します。

options, args = parser.parse_args() 

if args[0][0] == '@': # script.py @optfile 
    with open(args[0][1:]) as f: 
     fa = [l.strip() for l in f] 
    fa = fa + args[1:] # put back any other positional arguments 
    # Use your original parser to parse the new options 
    options, args = parser.parse_args(args=fa, values=options) 
0

私は最近のフラグとオプションとスクリプトの多くを構築した、と私は解決策を作ってみたがhereを説明しました。

基本的に私はoptionparserを特別なフラグでインスタンス化して、ファイルからオプションを読み込み、コマンドラインからオプションを指定したり、ファイルからそれらのオプションを指定したりすることができます。

アップデート:私はここにevalを使用する理由はありませんGitHub

関連する問題