見出し画像

python 初歩の初歩7/コマンドラインパラメータ

こんにちはmakokonです。
今日はpythonプログラムを実行するときのパラメータの話です。

想像してみてください。あなたが作成したPythonプログラムが、ただのコードの塊から、さまざまな条件下で動作する柔軟なツールへと変貌を遂げる瞬間を。これが、コマンドラインパラメータの力です。初心者プログラマーならなおさら、プログラムの起動時にこれらのパラメータを設定することで、その動作をカスタマイズすることができることに感動するでしょう。この記事では、その基本的な取り扱い方法から、さらに活用法までを簡潔に解説します。GUIアプリケーションの開発が増える一方で、コマンドラインパラメータの活用は、スクリプトの自動化や大量データの処理を効率化する上で依然として重要です。この機会に、プログラムの柔軟性と汎用性を高めるための第一歩として、コマンドラインパラメータの魅力に触れてみましょう。

コマンドラインパラメータ(コマンドライン引数)とは、例えば、
arg_sample00.pyというプログラムを実行するときに、通常は
$ python arg_sample00.py
のように実行しますが、このときに
$ python arg_sample00.py param1 param2
のように、実行のために必要なパラメータを与えるためのものです。

コマンドパラメータを確認してみよう

まずは体験します。以下のコードを書いて、lesson7.pyとして保存します。
def sample00()でコマンドパラメータを確認します。
今回は、
if __name__ == "__main__":
    sample00() # ここを書き換える
の形で、いろんなプログラムを呼び出すことにいます。

import sys

# コマンドラインパラメータを表示
def sample00():
    # パラメータの数を確認する
    print(f"パラメータの数は{len(sys.argv)}個です。")
    # sys.argvリストをイテレートし、パラメータを表示
    for i, arg in enumerate(sys.argv):
        print(f"パラメータ {i}: {arg}")

if __name__ == "__main__":
    sample00()

$ python lesson7.py 1 2 a b
パラメータの数は5個です。
パラメータ 0: lesson7.py
パラメータ 1: 1
パラメータ 2: 2
パラメータ 3: a
パラメータ 4: b

実行結果

今回の結果では、パラメータの数は5個(?4個指定したのに)
パラメータのリストを見ると、プログラム名が0番目に入っています。
1−4番目のパラメータが指定したパラメータでしたね。
簡単に解説します。
システム系の関数なので、import sys で準備をします。
問題のパラメータは、sys.argvという名前のリストで与えられます。
ですから、普通のリストのように、インデックスで要素を参照したり、for文で要素を取り出したり、各種リスト用のメソッドが使用できます。
このリストの特徴は、以下のようなものになります。

  • リストの最初の要素 (sys.argv[0]) は、スクリプトの名前(またはスクリプトへのフルパス)です。これは、プログラムが実行された方法によって異なります。

  • 残りの要素は、プログラム実行時にコマンドラインから渡された引数を順に含みます。

  • リストの長さ(len(sys.argv))は、引数の総数プラス1です(スクリプト名を含むため)。

パラメータのタイプを確認しよう

コマンドラインで2つの整数を入力して足し算しましょう。
def sample01(): 実は失敗例


def sample01():
    num1=sys.argv[1]
    num2=sys.argv[2]
    
    print(f"{num1} + {num2} = {num1 + num2}")
    

$ python lesson7.py 1 2
1 + 2 = 12

実行結果 sample01

あらら、1+2=12になっていまいました。sys.argvで与えられるパラメータは実は文字列なんですね。数値計算するなら、変数タイプを変更しないとダメみたいです。
じゃあ、修正版 def sample01_r() です。
int(sys.argv[1])とかすれば、良さそうですね。

def sample01_r():
    num1=int(sys.argv[1]) # パラメータを整数に変換する
    num2=int(sys.argv[2])
    
    print(f"{num1} + {num2} = {num1 + num2}")
    

$ python lesson7.py 1 2
1 + 2 = 3

実行結果 sample01_r

パラメータの数をちゃんと確認しよう

さて、2つのパラメータで足し算ができたわけですが、もし、パラメータが1つしかないと失敗しそうですね。実際、さっきのプログラムで試してみましょう。

$ python lesson7.py 2
Traceback (most recent call last):
(中略)
num2=int(sys.argv[2])
~~~~~~~~^^^
IndexError: list index out of range

「list index out of range」が発生しました。
存在しないパラメータを使おうとしたのだから当然ですね。
最低限 必要な数があるかどうかはチェックしましょう。
def sampel02() パラメータの数のチェック付きです。数が合わなかったらエラーの内容と、正しい使い方を表示して終了します。

def sample02():
    # コマンドライン引数の数が正しいかチェック
    if len(sys.argv) != 3:
        print("パラメータの数が正しくありません")
        print("使用法: python program.py 数値1 数値2")
        sys.exit(1)
        
    num1=int(sys.argv[1]) # パラメータを整数に変換する
    num2=int(sys.argv[2])
    
    print(f"{num1} + {num2} = {num1 + num2}")

$ python lesson7.py 1
パラメータの数が正しくありません
使用法: python program.py 数値1 数値2

$ python lesson7.py 1 2
1 + 2 = 3

$ python lesson7.py 1 2 3
パラメータの数が正しくありません
使用法: python program.py 数値1 数値2

実行結果 sample02

パラメータの数が2個のときは、合計を計算しそれ以外のときはエラーメッセージを出しました。

その他のエラー対策

他にも、数字でないパラメータが渡されるなどのエラーも考えられます。いきなりパラメータを渡すようなプログラムを書くときは、そのへんも配慮しましょう。
def sample03()  整数に変換できないエラーをチェックする機能を追加

def sample03():
    # コマンドライン引数の数が正しいかチェック
    if len(sys.argv) != 3:
        print("パラメータの数が正しくありません")
        print("使用法: python program.py 数値1 数値2")
        sys.exit(1)
    
    try:
        num1 = int(sys.argv[1])  # パラメータを整数に変換する
        num2 = int(sys.argv[2])
    except ValueError:  # 整数に変換できない場合のエラーハンドリング
        print("エラー: 数値1と数値2は整数である必要があります。")
        sys.exit(1)
    
    print(f"{num1} + {num2} = {num1 + num2}")

$ python lesson7.py abc
パラメータの数が正しくありません
使用法: python program.py 数値1 数値2

$ python lesson7.py 1 2
1 + 2 = 3
$ python lesson7.py 1 abc
エラー: 数値1と数値2は整数である必要があります。
$ python lesson7.py 1 2.3
エラー: 数値1と数値2は整数である必要があります。
$ python lesson7.py abc 1
エラー: 数値1と数値2は整数である必要があります。

実行結果 sampel03

オプション入力とデフォルト設定

私はLLMを用いたchatbotは形を変えてしょっちゅう作るのですが、大抵の場合、その変更は1行か2行書き換えるだけです。こういうのは、そもそも自動で答えてくれるのがいいですね。結構多用するモデル名と、言語の選択、maxtoken数を設定する方法を考えましょう。もちろん毎回設定するのがマストだと面倒なので、指定しない場合のデフォルトも使えるようにします。
使い方としては、python lesson7.py -model gpt-4 -lang jp -maketokens 200のようにします。
このような複雑な処理には、argparse を使用します。
def sample04() コマンドラインオプション解析

import argparse

def sample04():
    # パーサーを作成
    parser = argparse.ArgumentParser(description="コマンドラインオプションのデモ")

    # '-lang' オプションを追加
    parser.add_argument('-lang', default='jp',
                        help='言語を選択します。選択肢: [jp, en]')
    # '-maxltokens' オプションを追加
    parser.add_argument('-maxtokens', type=int, default=1024,
                        help='最大トークン長を指定します。範囲: 1-8192')
    # '-model' オプションを追加
    parser.add_argument('-model', default='gpt-3.5-turbo',
                        help='言語を選択します。選択肢: [jp, en]')

    # 引数を解析
    args = parser.parse_args()
    
    # 各種エラーチェック
    default_lang = parser.get_default('lang')
    if args.lang not in ['jp', 'en']:
        print(f"'-lang' の指定が無効です。デフォルト値 '{default_lang}' を使用します。")
        args.lang = 'japanese'
    
    default_maxtokens = parser.get_default('maxtokens')  
    if not 1 <= args.maxtokens <= 8192:
        print(f"'-maxtokens' の指定が範囲外です。デフォルト値 '{default_maxtokens}' を使用します。")
        args.maxtokens = 1024

    default_model = parser.get_default('model')
    if args.model not in ['gpt-3.5-turbo', 'gpt-4','gpt-4-turbo-preview']:
        print(f"'-model' の指定が無効です。デフォルト値 '{default_model}' を使用します。")
        args.model = 'gpt-3.5-turbo'

    

    # 解析したオプションを表示
    print(f"選択されたモデル:{args.model}")
    print(f"選択された言語: {args.lang}")
    print(f"指定された最大トークン長: {args.maxtokens}")

$ python lesson7.py
選択されたモデル:gpt-3.5-turbo
選択された言語: jp
指定された最大トークン長: 1024
$ python lesson7.py -model gpt-4
選択されたモデル:gpt-4
選択された言語: jp
指定された最大トークン長: 1024
python lesson7.py -model gpt-4 -lang en
選択されたモデル:gpt-4
選択された言語: en
指定された最大トークン長: 1024
$ python lesson7.py -model gpt-4 -lang en -maxtokens 4096
選択されたモデル:gpt-4
選択された言語: en
指定された最大トークン長: 4096
$ python lesson7.py -model test -lang fr -maxtokens 10000
'-lang' の指定が無効です。デフォルト値 'jp' を使用します。
'-maxtokens' の指定が範囲外です。デフォルト値 '1024' を使用します。
'-model' の指定が無効です。デフォルト値 'gpt-3.5-turbo' を使用します。
選択されたモデル:gpt-3.5-turbo
選択された言語: japanese
指定された最大トークン長: 1024

実行結果 sample04

parser.add_argument を使って書くオプションの名前、デフォルト値などを設定します。
args = parser.parse_args() を使って、各オプションの解析をします。
取得したオプションが想定している範囲内にあるかどうかをチェックして、範囲外であれば、デフォルト値を設定します。
もちろん、何も設定しなければ、デフォルト値が採用されます。

このように、適切なオプションを必要に応じてコマンドラインから渡すことができるようになります。

コマンドラインパラメータを利用する意味

プログラムを書いていて、状況に応じて設定を変更するためには、コマンドラインパラメータを利用するばかりでなく、他の方法を使用することができます。
ここでは、コマンドラインパラメータを利用する意味や、それをプログラム中でのinput文や設定ファイルを読み込む方法と使い分ける理由について説明します。

コマンドラインパラメータの利用意義

  1. 自動化とスクリプト化の容易さ: コマンドラインパラメータを使うと、プログラムをバッチ処理やスクリプトから簡単に呼び出し、自動化することができます。各種パラメータをプログラム起動時に指定できるため、入力の手間を省き、処理の自動化が容易になります。

  2. 柔軟性と汎用性の向上: プログラムをより汎用的にすることができます。同じコードで異なるデータセットを処理したり、動作モードを切り替えたりすることができます。コマンドラインパラメータを使うことで、プログラムの再利用性と柔軟性が高まります。

  3. ユーザーインターフェースの簡素化: GUIの開発なしに、ユーザーがプログラムの動作をコントロールできる手段を提供します。特に、バックエンド処理やサーバーで動作するアプリケーションでは、GUIよりもコマンドラインの方が適している場合が多いです。

input文や設定ファイルとの使い分け

  • input文の利用: ユーザーからのインタラクティブな入力が必要な場合や、プログラムの実行中にパラメータを変更する必要がある場合に適しています。ただし、自動化やバッチ処理には不向きです。

  • 設定ファイルの利用: 複雑な設定や多数のパラメータを管理する場合に適しています。設定ファイルを使うことで、設定の変更を容易にし、プログラムの再実行が簡単になります。しかし、設定ファイルの読み込みや解析のコードを書く必要があります。

  • コマンドラインパラメータの利用: スクリプト化や自動化が必要な場合、または簡単なパラメータの変更で複数のモードでプログラムを実行したい場合に最適です。設定ファイルよりも即時性があり、input文よりも自動化に適しています。

まとめ

コマンドラインパラメータ、input文、設定ファイルのどれを使うかは、プログラムの用途や運用のシナリオによって異なります。自動化の必要性、パラメータの複雑さ、ユーザーとのインタラクションの必要性を考慮して、適切な入力方法を選択することが重要です。

全体まとめ

pythonプログラムを起動するときに設定できるコマンドラインパラメータ(引数)について説明しました。
パラメータは、プログラム中で通常のリストとして扱うことができ、様々な処理を記述することができます。
引き渡されたパラメータは、単なる文字列のリストであり、処理によっては適切なタイプ変換やエラーチェックが必要です。
パラメータを利用してオプション設定を行う方法を紹介しました。

このように、コマンドラインパラメータを利用することによって、プログラウの起動時に様々な設定を追加できるようになり、プログラムの汎用性と自動化などのスクリプト処理を用意に行うことができます。GUIアプリを書くことも増えましたが、素早い処理や大量のデータ処理などはターミナルコマンドで処理するほうがはるかに楽なので、コマンドラインパラメータの重要性が下がることはないと思います。みなさんもぜひ積極的に利用してみてください。

#python #コマンドライン #パラメータ #オプション #デフォルト #コマンドラインパラメータ #プログラム #初歩 #エラー対策 #リスト #初歩の初歩 #sys .args #args #argparse

おまけ タイトル画の説明 by gpt-4-vision


画像は、プログラミングやソフトウェア開発の概念を色鮮やかに表現したアートワークです。中心に配置されたパソコンの画面には、イラスト化された白熱電球が描かれ、コードの断片が周りを取り囲んでいます。手前には、キーボードをタイピングしている手があり、横にはマウスが見えます。背景には、様々なアプリケーションのアイコン、グラフ、メール、雲のシンボル、ギアなどがデジタルな空間を表現するための要素として描かれています。全体的に、デジタルテクノロジーと創造性を象徴しているビビッドな色合いと活動的な雰囲気が特徴です。


この記事が気に入ったらサポートをしてみませんか?