見出し画像

【プログラミング】Pythonをコマンドプロンプトで実行する

最近、携わらせてもらっている業務のおかげで、pythonをコマンドプロンプトで実行することが限りなく増えた。(厳密にいうと、PythonをC++上で動かすのに、バッチファイルを作成して呼び出すことが増えた。Pythonをコマンドプロンプトで0~100まではやったことないのであしからず)
独特なので、すこしまとめようと思う。
(仕事でもこのnoteをメモ代わりに見る可能性もあるので。。)

下記を参考にしてます


Pythonファイルを実行してみよう

まずは、Pythonのパスがどこにとおってるのか、versionは何かをみてみよう。

where python
python --version

-- はコマンドラインでオプションやフラグを指定する際によく使われる記号。スクリプトに引数を渡すときなんかによく使う。

これで、自身の実行環境を確認するところから始めてみよう。

ディレクトリを移動 or 仮想環境を構築

cd C:\Users\yourusername\projects\myscripts

で指定したパス内にディレクトリを移動することができる。
cd は "change directory"の略。

仮想環境を構築したい場合は

python -m venv myenv(仮想環境名)

で構築し、

myenv\Scripts\activate

とすることで仮想環境をアクティベートすることで仮想環境内でpythonを使用できるようになる。(アクティベートしないと、せっかく構築した仮想環境を使用してくれないので注意しよう。)

仮想環境を構築できたら

pip install パッケージ名

で仮想環境に必要なパッケージをインストールする。

pip をアップグレードする場合は

python -m pip install --upgrade pip

仮想環境を終了する場合は

deactivate

で終了できる。

仮想環境を構築するメリットとしては以下のことが考えられる。

  • 仮想環境を使うことでそれぞれのプロジェクトが独立した環境で動作する

  • グローバル環境(システム全体に影響する環境)を汚さないでいい

  • 特定のバージョンのパッケージを使用できる

  • 再現性を確保できる

Pythonスクリプトの実行

次に実行したいPythonファイルを以下のコマンドで実行する

python your_script.py

これで、ディレクトリ(仮想環境)内のpythonファイルが実行される。ちなみに、pythonファイル内の関数に引数を渡すときは以下のように書く。

python your_script.py 引数1 引数2

(例)

# example_script.py
import sys

# 関数の定義
def add_numbers(a, b):
    return a + b

# コマンドライン引数を受け取る
if len(sys.argv) < 3:
    print("Usage: python example_script.py <num1> <num2>")
else:
    num1 = int(sys.argv[1])
    num2 = int(sys.argv[2])
    result = add_numbers(num1, num2)
    print(f"The result is: {result}")

に対して

python example_script.py 5 10

と書くと、sys.argv を通じて 5 と 10 が関数 add_numbers に渡され、下記が出力されます。

The result is: 15

また、python example_script.py 5 10でexample_script.py内に2つ関数があってそれぞれに異なる引数を入れる場合はargparse モジュールを使って、関数名とその引数を指定できるようにします。Pythonスクリプト内で関数を直接コマンドプロンプトから呼び出すには、一般的には標準のPython機能ではなく、モジュールとしてスクリプトを扱うことが必要。

#example_script.py

import argparse

def add_numbers(a, b):
    return a + b

def multiply_numbers(x, y):
    return x * y

def main():
    parser = argparse.ArgumentParser(description='Perform arithmetic operations.')
    subparsers = parser.add_subparsers(dest='command', required=True)
    
    add_parser = subparsers.add_parser('add', help='Add two numbers')
    add_parser.add_argument('a', type=int, help='First number')
    add_parser.add_argument('b', type=int, help='Second number')
    
    multiply_parser = subparsers.add_parser('multiply', help='Multiply two numbers')
    multiply_parser.add_argument('x', type=int, help='First number')
    multiply_parser.add_argument('y', type=int, help='Second number')
    
    args = parser.parse_args()
    operations = {
        'add': add_numbers,
        'multiply': multiply_numbers
    }
    
    result = operations[args.command](args.a, args.b) if args.command == 'add' else operations[args.command](args.x, args.y)
    print(f'Result: {result}')

if __name__ == '__main__':
    main()
python example_script.py multiply 5 10

なんだかややこしい。。(これなら、関数の引数が多くなってきたら大変だから、おそらく引数は少ないに越したことはない)

実行手順

1:レポジトリをgithubからsourcetreeを使ってクローンする

他の人にプログラムを共有するときに使うことが多いのが、githubとsourcetreeである。これらを使えば、一つのプログラムを複数人で分担して記述(編集)することができる。
githubとsourcetreeの簡単な使用方法については下記参照。

2:コマンドプロンプトでクローンしたフォルダに環境を移動

1でクローンしたフォルダ内に環境を移動する。環境の移動方法は上記でも説明した通り下記で行う

cd クローンしたフォルダがあるパス

3:仮想環境を作成しアクティベート

仮想環境を作成しアクティベートする

python -venv 仮想環境名
仮想環境名\Scripts\activate

4:setup.pyを実行

仮想環境内に必要なパッケージをインストールする。

python -c "import パッケージ名; print(パッケージ名.__version__)"

-cはcommandの略。;で改行する。

まとめてインストール(仮想環境をととのえる)setup.pyを作っておけばなおいいだろう。

python setup.py

5:コマンドプロンプトで仮想環境内のpythonファイルを実行

あとは、コマンドプロンプトを用いて仮想環境内で作成したpythonファイルを実行するだけである。引数の指定は下記のように行う。

python 実行対象.py 引数リスト

よく使われる関数

sys

sys.argv: コマンドライン引数のリスト

  • Pythonスクリプトにコマンドラインから引数(コマンドライン引数という)を渡したいときに使います。

  • sys.argv[0] にはスクリプトのファイル名が入り、以降に指定した引数がリストとして格納されます。

import sys
print(sys.argv)
print(sys.argv[1])
print(sys.argv[2])

コマンドプロンプトで

python script.py arg1 arg2

出力

['script.py', 'arg1', 'arg2']
['arg1']
['arg2']

なので、コマンドプロンプト引数を関数に渡すときによく使う。

sys.exit(): プログラムの終了

  • プログラムを強制的に終了させるために使用します。エラーステータスを返すこともできます。

import sys
sys.exit("Program terminated")

sys.path: Pythonモジュールの検索パス

  • Pythonがモジュールをどの場所で探すかを管理するリストです。外部ライブラリやモジュールの場所を指定する場合に役立ちます。

import sys
print(sys.path)

sys.stdin, sys.stdout, sys.stderr: 標準入力・出力・エラー

  • sys.stdin: 標準入力(通常はキーボード)を表します。

  • sys.stdout: 標準出力(通常はコンソール)を表します。

  • sys.stderr: エラーメッセージの出力先です。

import sys
sys.stdout.write("Hello, stdout!\n")
sys.stderr.write("Error message\n")

if __name__ == "__main__"/: main()

1. if __name__ == "__main__": の意味

この条件文は、スクリプトが直接実行されているかどうかを確認するためのもの。

  • スクリプトが直接実行された場合(例: python myscript.py): __name__ は "__main__" となるので、この条件が真となり、以下の main() 関数が実行されます。

  • 他のモジュールからインポートされた場合: __name__ は "__main__" ではないため、この条件は偽となり、main() は実行されません。

 __name__

Pythonの特殊な変数で、「コマンドプロンプトで直接実行されたとき」か「インポートされて実行されたとき」で下記のようにnameに文字列が格納される。

  • 直接実行されたとき: もしファイルがコマンドラインやエディタから直接実行された場合、__name__ は "__main__" に設定される。

  • インポートされたとき: 他のスクリプトやモジュールからインポートされた場合、そのモジュールの __name__ 変数には、そのモジュールの名前が設定される。

よくわからないと思うで、下記の記事を参考に簡単な例を下記に示す。

#sample.py
def hello():
    print('Hello')

if __name__ == '__main__':
hello()

というsample.pyがあったとする。

これをコマンドプロンプト上で実行すると

python sample.py // pyファイルの実行コマンド
Hello

となる。これは、sample.py内の__name__にmainが入るためif文がtureとなりhello()関数が実行されるためである。

このsample.pyをほかのファイルで呼び出して使用したい場合に、if __name__ == '__main__': が生きてくる。
example.pyというファイルで呼び出してsample.py内にhello()関数を使用したいとする。

# example.py
from sample import hello

hello()  # sample.py の hello() 関数を呼び出す

これをコマンドプロンプトで実行すると

python example.py
Hello

となる。これは、example.pyでsample.pyのhello() 関数が実行されて "Hello" と表示されますが、sample.py 内の if __name__ == '__main__': hello() は実行されないためである。もしsample.py 内の if __name__ == '__main__': hello()がなければ

Hello
Hello

となってしまう。(読み込み先のファイル(sample.py)に記載されている関数(hello())が実行されるため。)

main() 関数

main() 関数は、スクリプトのメイン処理をまとめるための関数。大規模なスクリプトやモジュールでは、コードを整理して理解しやすくするために、メイン処理を main() 関数にまとめることがよくある。

例:

def main():
    print("This script is running directly.")

if __name__ == "__main__":
    main()

このコードの動作:

  • 直接このスクリプトを実行すると、「This script is running directly.」と表示される。

  • 他のスクリプトでこのファイルをインポートした場合、main() は実行されない。

os

Pythonのosモジュールは、オペレーティングシステムとのインタラクションを提供するための標準ライブラリ。
ファイルやディレクトリの操作
環境変数の取得
プロセス管理
などを行うことができます。

1. ファイルおよびディレクトリの操作

  • os.path.join(path, *paths)

  • 複数のパスを結合して1つのパスを作成します。OSに依存せずにパスを結合できます。

os.path.join('folder', 'file.txt') → 'folder/file.txt'
  • os.path.exists(path)

  • 指定したパスが存在するかどうかを確認します。

os.path.exists('file.txt') #→ True または False
  • os.path.basement(path)

  • 指定したフルパスの最後の部分(ファイル名と拡張子)を返します。

os.path.basement(file/path/example.pcd)

example.pcd
  • os.makedirs(path, exist_ok=False)

  • 指定したパスのディレクトリを作成します。exist_ok=True にすると、既にディレクトリが存在してもエラーになりません。

os.makedirs('new_folder', exist_ok=True)

2. 現在の作業ディレクトリ

  • os.getcwd()

  • 現在の作業ディレクトリを取得します。

os.getcwd() #→ 'C:\\Users\\username\\project'
  • os.chdir(path)

  • 現在の作業ディレクトリを変更します。

os.chdir('new_directory')

3. 環境変数の操作

  • os.getenv(key, default=None)

  • 指定した環境変数の値を取得します。環境変数が存在しない場合、default を返します。

os.getenv('HOME') #→ ユーザーのホームディレクトリ
  • os.environ

    • 環境変数を表す辞書です。os.environ['KEY'] で値を取得または設定できます。

os.environ['PATH'] #→ 環境変数 PATH の値

import os

# 現在の作業ディレクトリを取得
current_dir = os.getcwd()
print(f"Current Directory: {current_dir}")

# 新しいディレクトリを作成
os.makedirs('new_directory', exist_ok=True)

# 新しいディレクトリに移動
os.chdir('new_directory')

# 現在の作業ディレクトリを確認
print(f"Changed Directory: {os.getcwd()}")

# 以前のディレクトリに戻る
os.chdir(current_dir)

# ファイルの存在確認
file_exists = os.path.exists('some_file.txt')
print(f"File Exists: {file_exists}")

# ファイル削除(存在する場合)
if file_exists:
    os.remove('some_file.txt')

Pythonのバージョンを変更する

「このパッケージ使いたいけどpip install が通らない。。」
「なに!?このパッケージはversoin3.11以上が必要なの!?」
「せっかくPythonを仮想環境にダウンロードしたのに。。。」

というシチュエーションはないだろうか。

そんな時には、pythonのバージョンを変更することがいい解決策になる。

まずは、pythonをダウンロードする(下記参照)

まず、現在のパスのなかでどこにpython環境があるのかを確認

where python

ついでに、pythonのversion確認

python --version

先ほどインストールしたpythonのバージョンに変更するには、そのパスを第一優先で通せばいい。

例えば、python3.8から3.11に変更したいとする。

3.11のパスを通すのは下記をコマンドプロンプトで実行する

set PATH=C:\path to python version 3.11\Python311\;%PATH%

元のpythonのバージョンに戻したいときは同様の方法で行えばいい

#3.8のパスにもどす(3.8のパスを第一優先にする)
set PATH=C:\path to python version 3.8\Python38\;%PATH%



Pythonのpip install がなかなか通らない。。。

解決方法① wheelをネットからダウンロードして、そのパスを指定してインストール

wheelとは、Pythonのパッケージを配布するためのフォーマット。拡張子が.whlのファイルです。
通常のpip installよりも高速にインストールが行えるため、特に依存関係が多い場合に便利である。

GDALやPDAL、opencvなどのリモートセンシング使うパッケージやC++やCMakeによるビルドが絡むパッケージはpip install でうまくいかないことが多い。

例ではGDAL3.4.3をダウンロードする場合を示している。

pip install "file path\file name.whl"

#GDAL -3.4.3wheelからインストールする場合
pip install "C:\path to wheel\GDAL-3.4.3-cp38-cp38-win_amd64.whl"

ちなみに、DAL-3.4.3-cp38-cp38-win_amd64.whlというファイルは、Python 3.8用のWindows 64ビット環境に対応したGDALライブラリのバージョン3.4.3のwheelファイルのことを指している。
しっかり、自身の環境にあったwheelをダウンロードしよう。

解決方法② anaconda環境を使っちゃえ!!

巷では、「環境構築にはpip が一番いい!だって誰のPCでも同じ環境を作れるもん」「いやいや、Anaconda一択でしょう」
というpip派かanaconda派がある。

私的には、①システム開発者などはpipを ②データサイエンスをする人や個人で課題が完結する場合はcondaを 使えばいいと思う

pipのほうが軽量でシンプルだが、condaはパッケージの依存関係を自動的に解決してくれるため、複雑な環境構築が簡単である。

pipでうまくいかない場合の大半が、複雑な環境構築のせいである(githubでダウンロードしたファイルをビルドして、それでできたファイルをどこどこに移して。。。∞)

そんな時は、一度condaで仮想環境を作り直して、インポートしてみるといい。(pdalはcondaが推奨されていたりする。)

ちなみに、conda install でインストールできない場合は、conda prompt上でpip install でインストールできれば、python上でimportできるようになる。

conda install

pip install 

の順で行えば確実である

解決方法③ 仮想環境を構築しなおす

上記2つでうまくいかない場合は、仮想環境を作り直そう。

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