35

に小さな問題がありargparseます。プロットのオプションxlimがあります。xrangeのような数字を渡せるようにしたい-2e-5。ただし、これは機能しません-argparseこれは位置引数であると解釈します。私がそれを行う場合、-0.00002それは機能します:argparseそれを負の数として読み取ります。読み込め-2e-3ますか?

コードは以下のとおりです。実行方法の例は次のとおりです。

./blaa.py --xlim -2.e-3 1e4 

私が次のことをすると、それは機能します:

./blaa.py --xlim -0.002 1e4 

コード:

parser.add_argument('--xlim', nargs = 2,
                  help = 'X axis limits',
                  action = 'store', type = float, 
                  default = [-1.e-3, 1.e-3])

このように機能させることはできますが、実際には科学的記数法を使用できるようにしたいと思います。誰かアイデアはありますか?

乾杯

4

7 に答える 7

40

私が見つけた回避策の1つは、値を引用することですが、スペースを追加します。あれは、

./blaa.py --xlim " -2.e-3" 1e4

このように、最初の文字はハイフンダッシュではないため、argparseは-2.e-3をオプション名とは見なしませんが、float(string)は左側のスペースを無視するため、floatに適切に変換されます。

于 2013-06-21T13:13:45.680 に答える
16

コメントですでに指摘されているように、問題は、-プレフィックスが引数ではなくオプションとして解析されることです。prefix_charsこれを回避する1つの方法は、引数を持つオプションに使用されるプレフィックスを変更することです。

#!/usr/bin/python
import argparse

parser = argparse.ArgumentParser(prefix_chars='@')
parser.add_argument('@@xlim', nargs = 2,
                  help = 'X axis limits',
                  action = 'store', type = float,
                  default = [-1.e-3, 1.e-3])
print parser.parse_args()

出力例:

$ ./blaa.py @@xlim -2.e-3 1e4
Namespace(xlim=[-0.002, 10000.0])

編集:または、-区切り文字として使用し続けxlim、単一の値として渡し、関数inを使用しtype て独自の解析を実装することもできます。

#!/usr/bin/python
import argparse

def two_floats(value):
    values = value.split()
    if len(values) != 2:
        raise argparse.ArgumentError
    values = map(float, values)
    return values

parser = argparse.ArgumentParser()
parser.add_argument('--xlim', 
                  help = 'X axis limits',
                  action = 'store', type=two_floats,
                  default = [-1.e-3, 1.e-3])
print parser.parse_args()

出力例:

$ ./blaa.py --xlim "-2e-3 1e4"
Namespace(xlim=[-0.002, 10000.0])
于 2012-01-27T09:37:00.443 に答える
14

オプションの値を等号で指定すると、次argparseで始まっていても、別のオプションとして扱われません-

./blaa.py --xlim='-0.002 1e4'
# As opposed to --xlim '-0.002 1e4'

また、値にスペースが含まれていない場合(またはシェルに指定されている他の特殊文字)、引用符を削除できます。

./blaa.py --xlim=-0.002

参照:https ://www.gnu.org/software/guile/manual/html_node/Command-Line-Format.html

これにより、受け入れられた回答が示唆するように、独自のtype=パーサーを記述したり、プレフィックス文字をから-に再定義したりする必要はありません。@

于 2018-03-02T00:19:39.250 に答える
9

これが私が使用するコードです。(これはjeremiahbuddhaに似ていますが、負の数を処理するため、質問に直接答えます。)

電話する前にこれを置いてくださいargparse.ArgumentParser()

for i, arg in enumerate(sys.argv):
  if (arg[0] == '-') and arg[1].isdigit(): sys.argv[i] = ' ' + arg
于 2014-01-30T02:36:14.283 に答える
7

=別の回避策は、引数を引用符で囲むことに加えて、''記号を使用して引数を渡すことです。--xlim="-2.3e14"

于 2014-12-09T17:43:31.190 に答える
4

自分自身を変更する場合はargparse.py、負の数のマッチャーを変更して科学的記数法を処理できます。

class _ActionsContainer.__init__()

self._negative_number_matcher = _re.compile(r'^-(\d+\.?|\d*\.\d+)([eE][+\-]?\d+)?$')

parser._negative_number_matcherまたは、パーサーを作成した後、この値に設定できます。このアプローチは、グループまたはサブパーサーを作成している場合に問題が発生する可能性がありますが、単純なパーサーで機能するはずです。

于 2013-03-15T06:22:05.710 に答える
3

andrewfnのアプローチに触発されて、いじくり回すための別のヘルパー関数を作成しましたsys.argv

def _tweak_neg_scinot():
    import re
    import sys
    p = re.compile('-\\d*\\.?\\d*e', re.I)
    sys.argv = [' ' + a if p.match(a) else a for a in sys.argv]

正規表現は以下を探します:

  • -:負の符号
  • \\d*:0桁以上(またはのような奇妙な形式の値の-.5e-2場合-4354.5e-6
  • \\.?:オプションの期間(たとえば、-2e-5合理的)
  • \\d*:0桁以上の別のセット(-2e-5およびなどの場合-7.e-3
  • e:指数マーカーと一致させる

re.I-2e-5との両方に一致させ-2E-5ます。使用p.matchとは、各文字列の先頭からのみ検索することを意味します。

于 2016-10-24T04:45:48.767 に答える