Django Python

[Python実践]argparseに挑戦してみよう!《add_argument編》

cardene

こんにちは!実務でPython、Djangoを使って、機械学習やWebアプリケーションの開発をしているかるでねです!

今回はPythonの「argparse」の基礎と「add_argument」の使い方について解説していこうと思います!

第1弾はこちら!

第3弾はこちら!

argparse」はコマンドライン引数を渡してくれるもので、Pythonエンジニアを目指している方は知っておいた方が良いものになります。

ぜひこの記事でマスターしていってください!

この記事はPythonの公式ドキュメントを参考にしています。

Pythonに限らず、プログラミング言語の公式ドキュメントは非常に読みにくいので、この記事でわかりやすく解説していきます。

argparse使ってみたい

コマンドライン引数を渡してみたい

argparseって何?

自作モジュール作ってみたい

他の人が書いたコードでargparseの部分がわからない

このような人のお役に立てれば幸いです。

それでは早速本題に入っていきましょう!

「argparse」はPythonの基礎を理解していないと難しいので、Pythonの基礎を理解していない人は以下を参考に学習してください!

概要

まずはargparseについて説明していきましょう。

argparseは一言で言えば以下のようになります。

コマンドライン引数を渡せる。

これではよくわからないですよね。

コマンドライン引数」とは、以下のようにPythonファイルを呼び出す際に渡せる値のことです。

python main.py --n cardene --age 30

少し詳しく説明すると、--nnameで今回はcardeneを渡しています。

--age30という値を渡しています。

def user_profile(name, age):
    print(name)
    print(age)

こんな感じの関数があったとして、cardenename引数に、30ageに渡されるということです。

どうでしょうか理解できたでしょうか?

このように引数が指定されることで、ユーザーごとにカスタムして使えるようにになります。

僕自身Pypiに自作モジュールをあげたことがあります。

Comnamepy

このモジュールもterminalでも使用することができ、その際にはコマンドライン引数を渡す必要があります。

この記事ではその方法を学んでいきます。

コマンドライン引数を設定する際、結構細かく設定できるのでぜひ全てマスターしていってください!

基本

まずは基本的な使い方をざっくりみていきます。

理解できなくても大丈夫なのでまずはみていきましょう!

まずはArgumentParserオブジェクトを作成することから始める。

import argparse

parser = argparse.ArgumentParser(description='かるでねブログ用のテストコード')

parserというオブジェクトを作成しました。

ここに2つのコマンドライン引数を追加していきます。

import argparse

parser = argparse.ArgumentParser(description='かるでねブログ用のテストコード')

parser.add_argument('name', type=str, nargs='+', default='cardene', help='username')
parser.add_argument('--age', '-a', nargs='+', type=int, help='user age')

args = parser.parse_args()

nameageという引数を追加しました。

terminalで確認してみましょう。

python main.py --h

usage: main.py [-h] [--age AGE [AGE ...]] name [name ...]

かるでねブログ用のテストコード

positional arguments:
  name                  username

optional arguments:
  -h, --help            show this help message and exit
  --age AGE [AGE ...], -a AGE [AGE ...]
                        user age

1行目のコマンドをterminalに入力すると以下のように出力されます。

--hhelpの略で、コマンドライン引数の使い方を確認できます。

positional argumentsは必須に引数です。

optional argumentsオプションの引数で、なくても問題ないものです。

コード上でどう指定するかというと、Pythonコードのname--ageの部分を見ればわかります。

--というのが先頭についているとオプション引数で、ついていないと必須引数となります。

早速コマンドライン引数を渡してみましょう!

terminalで以下のコマンドを実行してください。

python main.py cardene -a 30

namecardeneを渡し、age30を渡しました。

Namespace(name=['cardene'], age=[30])

そうすると上記のように出力されました。

ここまでで基本的な使い方を確認しました!

add_argument

前章の一番途中に作成したものがadd_argumentです。

add_argumentは1つ1つのコマンドライン引数を細かく設定するものです。

import argparse

parser = argparse.ArgumentParser(description='かるでねブログ用のテストコード')

parser.add_argument('name', type=str, nargs='+', default='cardene', help='username')
parser.add_argument('--age', '-a', nargs='+', type=int, help='user age')

args = parser.parse_args()

5行目、6行目がadd_argumentですね。

色々設定されているのが確認できますが何を設定しているのかわからないと思います。

この章で1つ1つ解説していくので学んでいってください!

引数一覧

ポイント

  • name flags
    • コマンドライン引数名。
  • type
    • コマンドライン引数の型。
  • default
    • コマンドライン引数のデフォルト値。
  • nargs
    • 受け取れるコマンドライン引数の数。
  • const
    • actionnargsの組み合わせで利用できる定数。
  • action
    • 引数が呼ばれた時のアクション。
  • choices
    • 選択肢からコマンドライン引数を選べる。
  • required
    • オプション引数を必須にするか任意にするか。
  • help
    • 引数が何なのかを示す簡潔な説明。
  • metavar
    • ヘルプメッセージの中で使われる引数の名前。
  • dest
    • parser_args()が返すオブジェクトに追加される属性名。

では早速1つ1つ確認していきましょう!

name, flags

「コマンドライン引数」の名前。

コマンドライン引数の名前を設定できます。

この部分で位置引数(必須引数)オプション引数かを指定できる。

指定方法としては接頭辞が使われる。

デフォルトでは--を名前の先頭につけることで自動でオプション引数と認識される。

この接頭辞は変更することができるので、以下の記事を参考にしてください。

位置引数

cardenenameなど。

オプション引数

--cardene--ageなど。

実際に見ていきましょう!

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, nargs='+', default='cardene', help='username')
parser.add_argument('--age', nargs='+', type=int, help='user age')

args = parser.parse_args()

5行目と6行目のname--ageコマンドライン引数名です。

terminalでpython main.py --hと実行してください。

usage: main.py [-h] [--age AGE [AGE ...]] name [name ...]

positional arguments:
  name                 username

optional arguments:
  -h, --help           show this help message and exit
  --age AGE [AGE ...]  user age

3行目のpositional arguments位置引」で、6行目のoptional argumentsオプション引数です。

--が先頭についてるものがオプション引数と認識されていますね。

type

「コマンドライン引数」のデータ型を指定する。

受け取ったコマンドライン引数の値のデータ型を指定したものに変更できます。

デフォルトではstrです。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')
parser.add_argument('--height', type=float, help='user age')


args = parser.parse_args()

print(args)

terminalでpython main.py cardene --age 20 --height 173.4と実行してください。

Namespace(name='cardene', age=20, height=173.4)

指定されたデータ型以外の値がくるとエラーが出ます。

terminalでpython main.py cardene --age 20.4 --height 173と実行してください。

usage: main.py [-h] [--age AGE] [--height HEIGHT] name
main.py: error: argument --age: invalid int value: '20.4'

--ageint型に指定されているので、20.4というfloat型を渡すとエラーが起きていますね。

自作関数

また自分で定義した関数を使用することもできます。

import argparse

parser = argparse.ArgumentParser()

def user_profile(profile):
    profile = '--'.join(profile.split())
    return profile

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')
parser.add_argument('--profile', type=user_profile, help='user age')


args = parser.parse_args()

print(args)

5行目にuser_profileという関数を定義しました。

この関数は受け取った文字列の空白を--に置換する関数です。

11行目で定義したuser_profile関数を指定しています。

では早速実行してみましょう。

terminalでpython main.py cardene --age 20 --profile "height 174.5 weight 56.5"と実行してください。

Namespace(name='cardene', age=20, profile='height--174.5--weight--56.5')

ちゃんと想定通りの出力がされていますね。

default

「コマンドライン引数」のデフォルト値を設定。

コマンドライン引数は通常指定しない限り呼び出されません。

しかし、デフォルト値を設定しておくと指定されなくても呼び出すことができます。

早速みてみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, default=20, help='user age')

args = parser.parse_args()

print(args)

5行目と6行目でdefault=と指定されているのがデフォルト値です。

位置引数は使えない

位置引数は通常、値を指定しないとエラーが起きるのでdefault値は使えません。

terminalでpython main.pyと実行してください。

usage: main.py [-h] [--age AGE] name
main.py: error: the following arguments are required: name

できていないのが確認できますね。

もし位置引数に対してdefaultを指定したい方は次の章のnargsを見てください。

指定していないオプション引数を取り除く

defaultargparse.SUPPRESSと指定すると、コマンドライン引数から属性を追加しないようにできます。

まずは通常の出力を確認しましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')

args = parser.parse_args()

print(args)

terminalでpython main.py cardeneと実行してください。

Namespace(name='cardene', age=None)

ageを指定していませんが、Noneという値が入っていますね。

ここからageを取り除いてみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age', default=argparse.SUPPRESS)

args = parser.parse_args()

print(args)

terminalでpython main.py cardeneと実行してください。

Namespace(name='cardene')

ちゃんと消えていますね。

nargs

「コマンドライン引数」に渡せる数の調整。

1つのコマンドライン引数に渡せる値は通常1つです。

しかし、nargsを使用することで渡せる値の数を調整できるようになります。

まずは何も指定していないものから見ていきましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')

args = parser.parse_args()

print(args)

terminalでpython main.py cardene --age 30と実行してください。

Namespace(name='cardene', age=30)

こちらはちゃんと1つずつ値を渡したのでエラーがでませんでしたね。

では2つの値を1つのコマンドライン引数に渡してみましょう。

terminalでpython main.py cardene --age 30 40と実行してください。

usage: main.py [-h] [--age AGE] name
main.py: error: unrecognized arguments: 40

40を渡せるコマンドライン引数がないと言っていますね。

ではここから2つ以上の値を渡す方法などをみていきましょう。

2つ渡す

まずは2つの値を渡せるようにしてみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', nargs=2, type=int, help='user age')

args = parser.parse_args()

print(args)

6行目でnargs=2と指定していますね。

ここの数字を変更すると、その数の引数を受け取るように設定できます。

terminalでpython main.py cardene --age 30と実行してください。

usage: main.py [-h] [--age AGE AGE] name
main.py: error: argument --age: expected 2 arguments

「2つの値を受け取ることを想定している」と言われていますね。

terminalでpython main.py cardene --age 30 40と実行してください。

Namespace(name='cardene', age=[30, 40])

ちゃんと受け取ってくれていますね。

?

可能なら値を1つ受け取り、指定されていないときデフォルト値を使用。

先程2と指定いた部分に'?'と指定することで、位置引数でdefaultを使用することができるようになります。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', nargs='?', type=str, default='cardene', help='username')
parser.add_argument('--age', nargs='?', type=int, default=10, help='user age')

args = parser.parse_args()

print(args)

5行目と6行目で'?'と指定していますね。

では、terminalでpython main.pyと実行してください。

Namespace(name='cardene', age=10)

前述ではエラーになりましたが、今回はエラーにならず位置引数のデフォルト値を指定できていますね。

*

複数の値を受け取る。

'*'と指定することで複数の値を受け取ることができます。

数字を指定すると、ちょうどその数の値を渡さないといけないですが、'*'では1つ以上の値ならいくつでも受け取ることができます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', nargs='*', type=int, help='user age')

args = parser.parse_args()

print(args)

6行目でnargs='*'と指定していますね。

terminalでpython main.py cardene --age 10 20 30と実行してください。

Namespace(name='cardene', age=[10, 20, 30])

ageが複数の値を受け取れているのが確認できますね。

+

複数の値を受け取るが、デフォルト値を使用できない。

*と同じで複数の値を受け取ることができます。

しかし、位置引数のデフォルト値が使用できません。

比較しながらみていきましょう。

*の時
import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', nargs='*', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')

args = parser.parse_args()

print(args)

terminalでpython main.pyと実行してください。

Namespace(name='cardene', age=None)

*ではエラーにならずデフォルト値を使用できていますね。

+の時
import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', nargs='+', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')

args = parser.parse_args()

print(args)

terminalでpython main.pyと実行してください。

usage: main.py [-h] [--age AGE] name [name ...]
main.py: error: the following arguments are required: name

nameが必要というエラーが出ていますね。

このように使い分けができるの参考にしてください。

const

ArgumentParserのアクションや「コマンドライン引数」のデフォルト値として使用。

constは単体で使われることはありません。

何かと合わせて使われることがメインです。

action

「コマンドライン引数」の処理を指定。

渡されたコマンドライン引数に対してさまざまな処理ができます。

1つ1つみていきましょう。

store

渡された値をそのまま格納。

storeactionのデフォルトになっています。

特別なことはせず、ただ渡された値を格納するだけです。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username')
parser.add_argument('--age', type=int, help='user age')

args = parser.parse_args()

print(args)

デフォルトになっているので特に指定する必要もないです。

terminalでpython main.py cardene 30と実行してください。

Namespace(name=['cardene', '30'], age=None)

今まで散々みてきたものですね。

store_const

const引数に指定された値を格納。

一見デフォルト値のような使い方なので違いを見ていきます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', type=str, default='cardene', help='username',)
parser.add_argument('--age', type=int, help='user age', default=10)


args = parser.parse_args()

print(args)

terminalでpython main.py cardene --ageと実行してください。

usage: main.py [-h] [--age AGE] name
main.py: error: argument --age: expected one argument

通常値を入力せずに「コマンドライン引数」だけを渡した場合エラーになります。

では次にstore_constをみていきましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--num', action='store_const', const=10)

args = parser.parse_args()

print(args)

5行目でaction='store_const', const=10と指定していますね。

先ほどと同じようにterminalでpython main.py --ageと実行してください。

Namespace(num=10)

前回はエラーになりましたが、今回はエラーにならずconstで指定した値が使われていますね。

通常はdefaultで指定した値が優先されます。

store_true , store_false

store_constの特別版。

先ほどみてきたstore_constとほとんど同じです。

どこが違うかというと、constを使用せずにTrueFalseのどちらかを返すようなものです。

実際に見て理解しましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--t', action='store_true')
parser.add_argument('--f', action='store_false')

args = parser.parse_args()

print(args)

5行目と6行目でそれぞれ、action='store_true'action='store_false'と指定していますね。

trueTrueを返し、falseFalseを返します。

ではterminalでpython main.pyと実行してください。

Namespace(t=False, f=True)

TrueFalseが出力されましたね。

append

「コマンドライン引数」をまとめる。

同じコマンドライン引数を複数回呼び出した際に1つにまとめてくれます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--num', action='append')

args = parser.parse_args()

print(args)

5行目でaction='append'と指定していますね。

terminalでpython main.py --num 10 --num 20 --num 30と実行してください。

Namespace(num=['10', '20', '30'])

ちゃんと1つにまとめてくれていますね。

append_const

「コマンドライン引数」をconstの値でまとめる。

値を指定せずに同じコマンドライン引数を複数回呼び出した際に1つにまとめてくれます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--num', action='append_const', const=10)

args = parser.parse_args()

print(args)

5行目でaction='append_const', const=10と指定していますね。

terminalでpython main.py --num --num --numと実行してください。

Namespace(num=[10, 10, 10])

ちゃんとconstの値で1つのリストにしてくれていますね。

count

キーワード引数の数を数える。

何個の値が渡されているか数えてくれます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--count', action='count')

args = parser.parse_args()

print(args)

5行目でaction='count'と指定していますね。

terminalでpython main.py --count --count --countと実行してください。

Namespace(count=3)

3個の値が渡されているのがわかりますね。

help

ヘルプを出力。

こちらは今まで散々見てきているものです。

-h--helpと同じものを呼び出して終了します。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--count', action='help')

args = parser.parse_args()

print(args)

5行目でaction='help'と指定していますね。

terminalでpython main.py --countと実行してください。

usage: main.py [-h] [--count]

optional arguments:
  -h, --help  show this help message and exit
  --count

ちゃんとhelpと同じものが出力されていますね。

version

バージョン情報を出力。

よくみるやつですね。

指定したバージョン情報を出力します。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--ver', action='version', version='%(prog)s 3.2')

args = parser.parse_args()

print(args)

5行目でaction='version', version='%(prog)s 3.2'と指定していますね。

progはプログラム名が入ります。

詳しくはこちらを参考にしてください。

今回はバージョンを3.2としました。

terminalでpython main.py --verと実行してください。

main.py 3.2

ちゃんと予想通り出力されていますね。

choices

選択肢から値を選べる。

コマンドライン引数の値を入力する際に、選択肢を用意してそこから選べるようにできる。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--choice', choices=['cardene', 'かるでね', 'カルデネ'])

args = parser.parse_args()

print(args)

5行目でchoices=['cardene', 'かるでね', 'カルデネ']と指定していますね。

terminalでpython main.py -hと実行してください。

usage: main.py [-h] [--choice {cardene,かるでね,カルデネ}]

optional arguments:
  -h, --help            show this help message and exit
  --choice {cardene,かるでね,カルデネ}

5行目で選択肢が全て出力されていますね。

選択肢にない値を入力するとエラーになる。

choicesを指定すると選択肢以外の値を受け付けません。

terminalでpython main.py --choice aと実行してください。

usage: main.py [-h] [--choice {cardene,かるでね,カルデネ}]
main.py: error: argument --choice: invalid choice: 'a' (choose from 'cardene', 'かるでね', 'カルデネ')

aという値は選択肢にないよ」といわれていますね。

required

オプション引数を必須にするか選べる。

オプション引数が必須でないのは、このrequiredがデフォルトでFalseとなっているからです。

ではrequiredTrueにしてみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--requ')

args = parser.parse_args()

print(args)

terminalでpython main.pyと実行してください。

Namespace(requ=None)

デフォルトではFalseなので必須になっていません。

ではTrueにしてみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('--requ', required=True)

args = parser.parse_args()

print(args)

5行目でrequired=Trueと指定していますね。

terminalでpython main.pyと実行してください。

usage: main.py [-h] --requ REQU
main.py: error: the following arguments are required: --requ

--requは必須だよ!」といわれていますね。

ちゃんと必須にできたようです。

そもそもオプション引数を必須にするなら初めから位置引数にした方が良いので推奨されていません。

help

「コマンドライン引数」の説明。

特定のコマンドライン引数がどんなものかの説明をつけることができます。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', nargs='?', type=str, default='cardene', help='username')
parser.add_argument('--age', nargs='?', type=int, default=10, help='user age')

args = parser.parse_args()

print(args)

5行目と6行目でhelp='~'と指定していますね。

この部分に説明を入れてください。

terminalでpython main.py -hと実行してください。

usage: main.py [-h] [--age [AGE]] [name]

positional arguments:
  name         username

optional arguments:
  -h, --help   show this help message and exit
  --age [AGE]  user age

4行目と8行目で先ほど設定したメッセージが表示されていますね。

metavar

helpの「コマンドライン引数」を変更。

先ほどのhelpで出力された最後の行の[AGE]という部分を自分の好きなように指定できるということです。

デフォルトでは、位置引数はそのままでオプション引数--を外して大文字になっています。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', metavar='名前だよ!', help='username')
parser.add_argument('--age', metavar='年齢だよ!', help='user age')

args = parser.parse_args()

print(args)

5行目と6行目で、metavar='名前だよ!' , metavar='年齢だよ!'と指定しています。

terminalでpython main.py -hと実行してください。

usage: main.py [-h] [--age 年齢だよ!] 名前だよ!

positional arguments:
  名前だよ!        username

optional arguments:
  -h, --help   show this help message and exit
  --age 年齢だよ!  user age

先ほど指定した通りに表示されていますね。

dest

「コマンドライン引数」を渡した後の名前を変更。

こちらもわかりにくいですよね...。

実際に見て理解しましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', help='username')
parser.add_argument('--age', help='user age')

args = parser.parse_args()

print(args)

terminalでpython main.py cardene --age 10と実行してください。

Namespace(name='cardene', age='10')

この出力のnameageの部分を自分の好きな文字にカスタマイズできるということです。

では早速変更してみましょう。

import argparse

parser = argparse.ArgumentParser()

parser.add_argument('name', help='username')
parser.add_argument('--age', dest='年齢', help='user age')

args = parser.parse_args()

print(args)

6行目でdest='年齢'と指定していますね。

terminalでpython main.py cardene --age 10と実行してください。

Namespace(name='cardene', 年齢='10'

ちゃんと変更できましたね!

最後に

今回は「argparse」の基礎と「add_argument」の使い方について解説してきました。

今回の知識だけでは「argparse」を使いこなすことはできません。

しかし全部解説すると長くなってしまうので別記事で紹介しています。

ぜひそちらも併せて読んでいただければと思います。

自分で調べたい方はぜひ以下を参考にしてみてください。

普段はPythonやブロックチェーンメインに情報発信をしています。

Twiiterでは図解でわかりやすく解説する投稿をしているのでぜひフォローしてくれると嬉しいです!

-Django, Python
-,