1

コマンドラインからスタンドアロンプ​​ログラムとしても使用できるpythonモジュール mymod.py を作成しました。

mymod.py では、いくつかの関数 (キーワードを使用してデフォルト値を設定) とif __name__=="__main__"、モジュールをスタンドアロン プログラムとして使用するためのブロックを定義しました。

デフォルトのオプションのいくつかをオーバーライドできるようにしたいので、メインプログラムでそれimport argparseを使用してオプションを解析します。ディクショナリを使用してデフォルト値を保存します。これにより、いつかデフォルト値を変更する必要が生じた場合に、その値を 1 か所だけ変更するだけで簡単に変更できるようになります。

それは機能しますが、コードが「クリーン」ではないことがわかり、おそらく適切なpythonicの方法でそれを行っていないと思いました。

これは私が何をするかを示すおもちゃの例です:

#!/usr/bin/env python
#mymod.py

__default_options__={
  "f1_x":10,
  "f2_x":10
}

def f1(x=__default_options__["f1_x"]):
  return x**2

def f2(x=__default_options__["f2_x"]):
  return x**4

# this function is the "core" function which uses f1 and f2 
# to produce the main task of the program
def f(x=__default_options__["f1_x"],y=__default_options__["f2_x"]):
  return f1(x)+f2(y)

if __name__=="__main__":
  import argparse
  parser = argparse.ArgumentParser(description = "A toy application")
  parser.add_argument("--f1-x",help="the parameter passed to f1",
    default=__default_options__["f1_x"], type = float,dest = "x")  
   parser.add_argument("--f2-x",help="the parameter passed to f2",
     default=__default_options__["f2_x"], type = float, dest = "y")

  options= parser.parse_args()
  print f(options.x,options.y)

私のようにデフォルト値を渡すのは少し面倒で、おそらく Python と argparse の両方の精神に反します。

このコードをより pythonic に改善し、argparse を最大限に活用するにはどうすればよいでしょうか?

4

2 に答える 2

1

@Francesco がコメントに書いたように、デフォルト辞書はおそらく意図したとおりに機能しません。後で辞書が変更されても、関数はモジュールのロード中に持っていたデフォルトを保持します。ディクショナリの現在の値を追跡する方法は次のとおりです。

_default_options = {
    "f1_x":10,
    "f2_x":10
}

def f1(x=None):
    if x == None:
        x = _default_options["f1_x"]
    ...

その後、 またはその他の方法で変更でき、_default_options引数なしで呼び出された場合に使用されます。ArgumentParserf1()

これには、Noneが意味のある値になることは決してないことが必要ですx。そうでない場合は、適切な不可能値を選択してください。

于 2013-03-22T13:00:44.253 に答える
1

次の方法で、`ArgumentParser.set_defaultsメソッドを使用できます。

default_options={
    "x":10,
    "y":10
}

def f1(**kwargs):
    x=kwargs.get('x', defalut_options['x'])
    return x**2

def f2(**kwargs):
    y=kwargs.get('y', defalut_options['y'])
    return x**4

def f(**kwargs):
    x=kwargs.get('x', defalut_options['x'])
    y=kwargs.get('y', defalut_options['y'])
    return f1(x=x, y=y)

if __name__=="__main__":
    import argparse
    parser = argparse.ArgumentParser(description = "A toy application", formatter_class=argparse.ArgumentDefaultsHelpFormatter )
    parser.add_argument("--f1-x",help="the parameter passed to f1",
      type = float,dest = "x")
    parser.add_argument("--f2-x",help="the parameter passed to f2",
      type = float, dest = "y")

    parser.set_defaults(**default_options)

    options= parser.parse_args()
    print f(options.x,options.y)

destあなたがinを使用していることに気付かなかったので、機能させるのに少し時間がかかりましたadd_argument(私は使用したことがありません)。このキーワードが指定されていない場合、argparse はデフォルトdestを引数の長い名前に設定します (この場合はf1_xandf2_xに置き換え-られ_ます)。要点を言えば、デフォルトの辞書を提供したい場合、dest提供されている場合はキーが一致する必要があります。parser.set_defaultsさらに、パーサーに引数を追加するだけに注意してください。パーサーにないエントリがある場合は、 Namespace.

kwargs--関数にジェネリックを追加するために編集 --

于 2013-03-22T12:33:38.450 に答える