PythonとのCLIアプリ


この章では、CLI引数を使用するいくつかの例を示しますsys and argparse モジュールThe fileinput モジュールもこの章で紹介されています.

sysargv
Pythonプログラムの実行時に渡されるコマンドライン引数はlist 文字列のsys.argv . 最初の要素0 ) Pythonスクリプトの名前-c またはPythonインタプリタがどのように呼び出されたかによって空文字列です.要素の残りの部分は、実行されるスクリプトに沿って渡された場合、コマンドライン引数を持ちます.参照docs.python: sys.argv 詳細は
CLI引数として渡される2つの数を受け入れて、入力が正しく通過されたならば、合計を表示するプログラムは、ここにあります.
# sum_two_nums.py
import ast
import sys

try:
    num1, num2 = sys.argv[1:]
    total = ast.literal_eval(num1) + ast.literal_eval(num2)
except ValueError:
    sys.exit('Error: Please provide exactly two numbers as arguments')
else:
    print(f'{num1} + {num2} = {total}')
The ast.literal_eval() メソッドは文字列値を組み込みリテラルに変換するのに便利です.あなたが使いたいならばint() and float() 上記のプログラムでは、まず入力を整数と浮動小数点に分離するロジックを追加する必要があります.文字列をsys.exit()stderr streamと終了ステータスを設定する1 スクリプトの終了に加えて.
以下にサンプルを実行します.
$ python3.9 sum_two_nums.py 2 3.14
2 + 3.14 = 5.140000000000001
$ echo $?
0

$ python3.9 sum_two_nums.py 2 3.14 7
Error: Please provide exactly two numbers as arguments
$ echo $?
1
$ python3.9 sum_two_nums.py 2 abc
Error: Please provide exactly two numbers as arguments
運動として、上記のプログラムを修正するTypeError 例外.以下に示す出力の代わりに、ユーザーにエラーを知らせてくださいsys.exit() メソッド.
$ python3.9 sum_two_nums.py 2 [1]
Traceback (most recent call last):
  File "/home/learnbyexample/Python/programs/sum_two_nums.py", line 6, in <module>
    total = ast.literal_eval(num1) + ast.literal_eval(num2)
TypeError: unsupported operand type(s) for +: 'int' and 'list'
別の演習として、入力引数として一つ以上の数字を受け入れる.計算-入力、合計、製品と平均についての次の詳細を表示します.

File入力による場所編集
ファイルを適切に編集するにはfileinput module 便利です.ファイル名の上でループをCLI引数として通過するプログラムは、ここにあります.sys.argv[1:] ), いくつかの処理を行い、変更を元の入力ファイルに書き戻します.また、1つ以上のファイル名をfiles キーワード引数を指定します.
# inplace_edit.py
import fileinput

with fileinput.input(inplace=True) as f:
    for ip_line in f:
        op_line = ip_line.rstrip('\n').capitalize() + '.'
        print(op_line)
Note that unlike open() , the FileInput オブジェクトがサポートしませんwrite() メソッド.ただし、print() 十分です.以下にサンプルを実行します.
$ python3.9 inplace_edit.py [io]p.txt

$ # check if files have changed
$ cat ip.txt
Hi there.
Today is sunny.
Have a nice day.
$ cat op.txt
This is a sample line of text.
Yet another line.

$ # if stdin is passed as input, inplace gets disabled
$ echo 'GooD moRNiNg' | python3.9 inplace_edit.py
Good morning.

As inplace=True permanently modifies your input files, it is always a good idea to check your logic on sample files first. That way your data wouldn't be lost because of an error in your program. You can also ask fileinput to create backups if you need to recover original files later — for example, backup='.bkp' will create backups by adding .bkp as the suffix to the original filenames.



アルスパースsys.argv 簡単なユースケースに十分です.様々な種類のフラグと引数(いくつかのオプション/必須)を使用してCLIアプリケーションを作成したい場合などには、組み込みのようなモジュールを使用しますargparse またはサードパーティのソリューションのようなclick .
引用docs.python: argparse :

The argparse module makes it easy to write user-friendly command-line interfaces. The program defines what arguments it requires, and argparse will figure out how to parse those out of sys.argv. The argparse module also automatically generates help and usage messages and issues errors when users give the program invalid arguments.


ファイル名の一覧を含むファイルを受け入れるCLIアプリケーションです.同じ拡張子を持つファイルはさらに昇順でソートされます.また、重複するエントリを削除するオプションのフラグを実装します.
# sort_ext.py
import argparse

parser = argparse.ArgumentParser()
parser.add_argument('-f', '--file', required=True,
                    help="input file to be sorted")
parser.add_argument('-u', '--unique', action='store_true',
                    help="sort uniquely")
args = parser.parse_args()

ip_lines = open(args.file).readlines()
if args.unique:
    ip_lines = set(ip_lines)

op_lines = sorted(ip_lines, key=lambda s: (s.rsplit('.', 1)[-1], s))
for line in op_lines:
    print(line, end='')
CLIアプリケーションのドキュメントは、パーサーに渡された情報に基づいて自動的に生成されます.ヘルプオプション(自動的に追加されます)を使用して、以下のようにドキュメントを表示できます.
$ python3.9 sort_ext.py -h
usage: sort_ext.py [-h] -f FILE [-u]

optional arguments:
  -h, --help            show this help message and exit
  -f FILE, --file FILE  input file to be sorted
  -u, --unique          sort uniquely

$ python3.9 sort_ext.py
usage: sort_ext.py [-h] -f FILE [-u]
sort_ext.py: error: the following arguments are required: -f/--file
The add_argument() CLIアプリケーションのオプション/引数に関する詳細を追加できます.最初のパラメータは引数またはオプションを指定します- ). The help キーワード引数を使用すると、特定のオプション/引数のドキュメントを追加できます.参照docs.python: add_argument 他のキーワード引数に関するドキュメントと詳細については.
上記のプログラムは、ソートされるファイル名を保存するための2つのオプション、もう1つを追加します.拡張子に基づいてソートする必要のあるサンプルテキストファイルを示します.
$ cat sample.txt
input.log
basic.test
input.log
out.put.txt
sync.py
input.log
async.txt
ここでは、プログラムによってサポートされている両方の種類のソーティングを出力します.
# default sort
$ python3.9 sort_ext.py -f sample.txt
input.log
input.log
input.log
sync.py
basic.test
async.txt
out.put.txt

# unique sort
$ python3.9 sort_ext.py -uf sample.txt
input.log
sync.py
basic.test
async.txt
out.put.txt

See docs.python HOWTOs: Argparse Tutorial for a more detailed introduction.



stdinを受け入れる
CLIツールのようなツールgrep , sed , awk と他の多くのデータを受け入れることができますstdin ファイル名を引数として受け入れる.追加される前のプログラムstdin 機能を以下に示します.args.file はオプションの代わりに位置引数です.nargs='?' この引数がオプションであることを示します.type=argparse.FileType('r') 自動的にファイルハンドルを取得するread 引数として与えられるファイル名のモード.を返します.default=sys.stdin キックインし、ファイルハンドルを取得するstdin データ.
# sort_ext_stdin.py
import argparse, sys

parser = argparse.ArgumentParser()
parser.add_argument('file', nargs='?',
                    type=argparse.FileType('r'), default=sys.stdin,
                    help="input file to be sorted")
parser.add_argument('-u', '--unique', action='store_true',
                    help="sort uniquely")
args = parser.parse_args()

ip_lines = args.file.readlines()
if args.unique:
    ip_lines = set(ip_lines)

op_lines = sorted(ip_lines, key=lambda s: (s.rsplit('.', 1)[-1], s))
for line in op_lines:
    print(line, end='')
以下に修正プログラムのヘルプを示します.
$ python3.9 sort_ext_stdin.py -h
usage: sort_ext_stdin.py [-h] [-u] [file]

positional arguments:
  file          input file to be sorted

optional arguments:
  -h, --help    show this help message and exit
  -u, --unique  sort uniquely
両方を示しているサンプルstdin ファイル名引数の機能.
# 'cat' is used here for illustration purposes only
$ cat sample.txt | python3.9 sort_ext_stdin.py
input.log
input.log
input.log
sync.py
basic.test
async.txt
out.put.txt
$ python3.9 sort_ext_stdin.py -u sample.txt
input.log
sync.py
basic.test
async.txt
out.put.txt
運動として-o, --output オプションの引数で、上記プログラムのファイルに出力を保存します.