7

標準入力を取るオプションの引数を指定しようとしています。これは主に私のプログラムでデータをパイプするために使用されるので、someprog that outputs | python my_prog.

私はargparseのドキュメントに従いました.Stackoverflowでこれに関する多くの質問/回答を読みましたが、どれもうまくいかないようです.

これが私がもともと持っているものです:

parser = argparse.ArgumentParser(description='Upgrade Instance.')
parser.add_argument('--app', '-a', dest='app', action='store', required=True)
parser.add_argument('--version', '-v', dest='version', action='store', default='', required=False)
parser.add_argument('--config', '-c', dest='config', action='store', default = '', required=False)
args = parser.parse_args()

ここでやりたいことは、ユーザーがversionパイプを渡すのではなく、パイプを使用して渡すことを許可することです。

一番上に追加parser.add_argument('infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)しましたが、それは位置引数になります。そんなことがあるものか?nargs=?オプションにすると思いました。

オプションの引数にする必要があります。だから私はそれを次のように変更しました:

parser.add_argument('--infile', nargs='?', type=argparse.FileType('r'), default=sys.stdin)

これによりオプションの引数になりますが、パイプが渡されない場合、プログラムは stdin をデフォルトとして待機してハングします。を削除default=sys.stdinしてプログラムに何かをパイプすると、次のようになります。

close failed in file object destructor:
sys.excepthook is missing
lost sys.stderr

それを実行するとき。を印刷するとargs、次のようになりますNamespace(app='app', config='', g=False, hosts='03.app', infile=None, version='')

私がやっていることは非常に単純で一般的なようで、多くの人がそれについて尋ねてきました。しかし、それは私とはうまくいかないようです。

どうすればそれを機能させることができるかについて何か提案はありますか?

4

3 に答える 3

4

私はこの問題を自分で突っついていましたが、ここのオプションに小さな改善が見られました-将来の旅行者に役立つことを願っています. フラグを提供するときに stdinからのみ読み取ることを望んでいたかどうかは 100% 明らかではありませんが、それが目標だったようです。私の答えは、この仮定に基づいています。それが問題になる場合に備えて、私は3.4で作業しています...

次のようなオプションの引数を 1 つ宣言できます。

parser.add_argument("-v", "--version", nargs='?', const=sys.stdin, action=StreamType)

オプションが完全に存在しない場合にのみ使用され、フラグが存在するが引数がない場合にのみ const が使用されるため、デフォルトを指定していません。StreamType私が書いた小さなargparse.Actionサブクラスで、標準入力ストリームから行を読み取ろうとし、それが機能しない場合はそのままの値を保存します。

class StreamType(argparse.Action):
    def __call__(self, parser, namespace, values, option_string=None):
        try:
            setattr(namespace, self.dest, values.readline().strip())
        except AttributeError:
            setattr(namespace, self.dest, values)

これにより、次のようなものが生成されます。

$ blah --version v1.1.1
Namespace(version='v1.1.1')

$ echo "v1.0.3" | blah --version
Namespace(version='v1.0.3')
于 2015-04-19T19:59:21.957 に答える