前回の記事でPythonにおけるファイル操作の方法とファイル読み込み、書き込みといった処理方法について学びました。
今回は、プログラム作成時に他の関数などのモジュールを読み込み利用する方法について学んでいきたいと思います。
- モジュールとは何かがわかる
- モジュールの作成と利用の方法がわかる
モジュールとは
プログラムはある程度の規模になると、多くの関数やクラスを作成し利用することになります。
こうした時に困るのがプログラムが長くなりすぎることです。
長いプログラムは、他の人からも読みづらくなるし、後からの修正もしづらくなります。
正直、長いプログラムは読むのにうんざりするからねぇ
こういう時に、適度にプログラムを分割して役割を分担できるとプログラムとしても分かりやすくなります。
また、他のプログラムでも使えるような汎用性の高い関数やクラスを、どのプログラムからでも利用できるようになっていると、わざわざ同じプログラムを書いたりコピペせずに済みます。
こうした「適度な分割」や「プログラムの再利用」ということから考え出されたのが「モジュール」です。
モジュールはPythonのソースコードが記述されたスクリプトファイルのことです。
Pythonでは、スクリプトファイルにまとめたものをモジュールとして他のプログラムから読み込み利用できるようになっています。
モジュールをインポートする
では、モジュールを読み込んで使ってみましょう。
今回はPythonで標準実装されている「sys」というモジュールを利用します。
sysはシステム関連の情報を取得するための機能を提供するモジュールです。
プログラムでモジュールを読み込み、使えるようにするにはプログラムの先頭に以下の構文を記載します。
では、サンプルでプログラムを書いてみましょう。
import sys
print(sys.platform)
print(sys.version)
print(sys.version_info)
sys.exit(0)
1行目で「sys」のモジュールを読み込んでいます。
これでsysモジュール内にある関数が利用できます。
モジュール内の変数や関数、クラスを利用する際はモジュール名の後にドットをつけて呼び出します。
上記では、sysモジュール内にある「platform」「version」「version_info」変数と「exit()」関数にアクセスしています。
筆者の実行環境での実行した場合の結果は以下となります。
darwin
3.10.1 (main, Jan 21 2022, 00:16:36) [Clang 12.0.5 (clang-1205.0.22.11)]
sys.version_info(major=3, minor=10, micro=1, releaselevel='final', serial=0)
ちなみに上記で呼び出した変数、関数を簡単にまとめておくと以下となります。
プラットフォーム名(sys.platform)
実行環境(プラットフォーム)を表す変数です。使用している実行環境によって以下の文字列が得られます。
文字列 | 対応するOS |
---|---|
win32 | Windows |
darwin | Mac OS X(macOS) |
linux | Linux |
cygwin | WindowsのCygwin環境 |
バージョン名(sys.version)
使用しているPythonのバージョン名を表す変数です。単純な数値だけでなく長いテキストが設定されています。
バージョン情報(sys.version_info)
バージョン情報を細かな値ごとに保管する変数です。major、minor、micro、releaselevel、serialといった細かな値が保管されています。
プログラム終了(sys.exit())
プログラムを終了するメソッドです。引数として終了ステータスを表す値を指定できます。sys.exit(0)で、正常終了を表します。
標準ライブラリとモジュール
Pythonには標準で多数のモジュールが用意されていて、これらは「標準ライブラリ」と呼ばれています。
標準ライブラリはWindows、macOS、その他のOSでも変わりなく利用できます。
ちなみにPythonの標準ライブラリの詳細は以下で公開されています。
ここからリンクをクリックすれば、そのモジュールの説明ページが表示されますので、必要に応じてドキュメントで調べながら利用しましょう。
標準ライブラリーのモジュールで、よく使いそうなものは別の記事にまとめる予定です
モジュールの作成
では実際にモジュールを自作して、プログラムから呼び出してみましょう。
今回はごくごく簡単なモジュールを作成しますので、どういった感じでモジュールを作成してプログラムから呼び出すのかそのイメージをつかんで貰えたらと思います。
自作モジュールですが、機能としては名前を取得してリストに格納して、格納済みの名前を表示するモジュールです。
また格納している名前をソートする関数も用意しています。
data = []
def setname(name):
global data
data.append(name)
def getname():
global data
return data
def sortname():
global data
data.sort()
ファイル内のリスト型変数「data」に値を追加したり、リストをソートしたり、リストを返したりといったごくごく簡単なモジュールです。
上記のプログラムを記述したら、ファイル名を「name.py」として保存します。
ここで1点見慣れない変数があると思いますが、各関数内で「global data」と宣言しています。
これは関数内のローカル変数ではなく1行目に宣言している「data = []」を使いますよという意味です。
関数内から関数外の変数にアクセスする際の記法です。
特にPythonでは気軽に変数定義ができるため、変数の代入をしているつもりが同名の新しい変数宣言をしていたりするので、関数外の変数にアクセスする場合は明示的にグローバル変数を宣言しておいた方が良いでしょう。
では、上記モジュールを呼び出してみます。
import name
name.setname("Suzuki Taro")
name.setname("Maeda Daisuke")
name.setname("Sato Hanako")
namelist = name.getname()
print(namelist)
name.sortname()
namelist = name.getname()
print(namelist)
先ほどのモジュールファイル「name.py」と同一ディレクトリ内に、別のファイル「test.py」を作成します。
上記プログラムでは、1行目にモジュールの読み込みをしています。
これで「name.py」のモジュールが読み込まれて関数が使用可能となります。
それから3〜5行目で名前を追加して、リストを取得して表示しています。
その後、ファイルを名前順にソートして再度リストを取得し表示しています。
実行結果は以下となります。
['Suzuki Taro', 'Maeda Daisuke', 'Sato Hanako']
['Maeda Daisuke', 'Sato Hanako', 'Suzuki Taro']
上記により、自作したモジュールが正しく使えていることが確認できました。
モジュールのクラス化
では、上記のモジュールをクラス化して呼び出してみましょう。
まずはnameモジュールをクラスの形に書き直してみます。
class Name:
def __init__(self):
self.__data = []
def setname(self,name):
self.__data.append(name)
def getname(self):
return self.__data
def sortname(self):
self.__data.sort()
クラスNameを作成し、dataリストをプライベート変数にしました。
これでクラス外からdataリストを直接変更出来なくなりました。
では、上記クラスをモジュールとして呼び出してみましょう。
from name import Name
nm = Name()
nm.setname("Suzuki Taro")
nm.setname("Maeda Daisuke")
nm.setname("Sato Hanako")
namelist = nm.getname()
print(namelist)
nm.sortname()
namelist = nm.getname()
print(namelist)
はい、1行目のモジュール読み込みの記述が若干異なっています。
これは、ファイル内のクラスを読み込む場合はこのように記述します。
このように記載すると、nameモジュール内のNameクラスを「Name()」で直接インスタンスが作成できるようになります。
ちなみにクラスが複数ある場合は、カンマ区切りで読み込むことも可能ですし、ワイルドカード(*)で指定すればモジュール内にある全ての要素を読み込むことも可能です。
from モジュール import A,B,C # モジュール内のA,B,Cを読み込む from モジュール import * # モジュール内の全要素を読み込む
あとはNameのインスタンスを作成し、各メソッドを呼び出しています。
実行結果は先ほどと同じとなります。
['Suzuki Taro', 'Maeda Daisuke', 'Sato Hanako']
['Maeda Daisuke', 'Sato Hanako', 'Suzuki Taro']
モジュール単体で実行する
では、モジュール単体で実行した場合はどうなるでしょうか。
当然ですが、モジュールにはモジュールを動かす処理が書かれていないので何も実行せずに終わります。
では、プログラムの関数やクラス部分の一部をモジュール化したい場合はどうすれば良いでしょうか。
例えばプログラム単体でも動くし、モジュールとしても使えるようなプログラムを作るにはどうすれば良いでしょうか。
その場合は、プログラム単体で実行する時のみ呼び出される処理を追記し、その中で単体で実行する処理を記述すれば良いです。
実現する方法としては「__name__」という変数を使います。
上記の処理をモジュールの最後に追記し、単体プログラムで実施したい処理を追記すれば、単体プログラムでも使えますしモジュールとしても使えます。
これ、モジュール単体でのデバックとかにも使えそうですね
では、先ほどのモジュール呼び出しのプログラムをモジュール単体で動かしてみましょう。
class Name:
def __init__(self):
self.__data = []
def setname(self,name):
self.__data.append(name)
def getname(self):
return self.__data
def sortname(self):
self.__data.sort()
if __name__ == "__main__":
nm = Name()
nm.setname("Suzuki Taro")
nm.setname("Maeda Daisuke")
nm.setname("Sato Hanako")
namelist = nm.getname()
print(namelist)
nm.sortname()
namelist = nm.getname()
print(namelist)
15行目から、「if name == “main”:」と単体プログラムで実行した場合の処理を追記しています。
このプログラムを「name.py」単体で実施しても「test.py」からモジュールとして呼び出しても、同じ結果となります。
> python name.py
['Suzuki Taro', 'Maeda Daisuke', 'Sato Hanako']
['Maeda Daisuke', 'Sato Hanako', 'Suzuki Taro']
> python test.py
['Suzuki Taro', 'Maeda Daisuke', 'Sato Hanako']
['Maeda Daisuke', 'Sato Hanako', 'Suzuki Taro']
sys.argvでパラメータ利用
最後に、Pythonを実行する際にコマンドラインからの実行時にパラメータを複数渡すことが出来ます。
> python name.py aaa bbb ccc
こうすると、プログラム上に変数「sys.argv」にリストで[“name.py”,”aaa”,”bbb”,”ccc]と設定され、それらの値をプログラム内で使用することが出来ます。
では、先ほどのプログラムで設定した名前のリストをコマンドの引数で渡してみましょう。
import sys
class Name:
def __init__(self):
self.__data = []
def setname(self,name):
self.__data.append(name)
def getname(self):
return self.__data
def sortname(self):
self.__data.sort()
if __name__ == "__main__":
nm = Name()
flg = False
for arg in sys.argv:
if flg:
nm.setname(arg)
flg = True
1行目で「sys」モジュールを読み込みます。
20行目で「sys.argv」のリストを取得して、引数の2つ目以降の値を名前追加しています。
上記を実行時に、以下のように引数に名前を渡してみると実行結果は以下となります。
> python name.py 'Suzuki Taro' 'Maeda Daisuke' 'Sato Hanako'
['Suzuki Taro', 'Maeda Daisuke', 'Sato Hanako']
['Maeda Daisuke', 'Sato Hanako', 'Suzuki Taro']
実行時にコマンドラインの引数で値を渡して、その値をプログラム内で処理できました。
まとめ
今回は、Pythonでのモジュールの作成と利用の基本について学びました。