
ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第3回 「モジュール」学習メモ
はじめに
ノンプロ研で開催されている、「中級プログラミング講座【Pythonコース】」第1期 第3回の講座の内容と、学習したことなどを、講座の回毎にまとめていきます。
第3回のアジェンダは、「モジュール」です。
1.モジュール
Pythonの世界

Pythonには、標準機能、標準ライブラリだけではなく、同梱ライブラリ、そしてサードパーティー製のライブラリをimportすることで、Pythonの世界がぐんぐん広がります。
関数、オブジェクトを利用するには?

標準ライブラリや同梱ライブラリを使用する場合、モジュールを読み込む、つまりインポートする作業が必要です。
モジュールをインポートする場合、スクリプト内で毎回行う必要があります。
モジュールのインポートと利用方法


インポートしたモジュールを利用するには、インポートしたモジュール名.コードで使用することができるようになります。
import文でビルトインスコープに持ってくるというイメージです。
このコードには、インポートしたモジュールで定義されている関数、オブジェクトなどを指定することができます。
モジュールとは?

関数、クラスは、プログラムを部品化するための手法の1つです。
モジュールも、部品化する手法の1つで、単位がコードを収めたPythonファイルとなります。
モジュールを利用するメリットは、下記2つがあげられます。
よく利用する関数などをその都度定義する必要がなくなるため、効率的にコーディングすることができる
シンプルで可読性の高いコードを書くことができる
__name__
演習では、calc.pyというモジュールを作成し、作成したcalcモジュールを別のスクリプト(3-01.py)を実行して動作を確認していきます。
calc.pyファイル
def calc_area(x, y):
return x * y
x = 2
y = 3
print(calc_area(x, y))
3-01.pyファイル
import calc
print(calc.x)
height, width = 3, 5
print(calc.calc_area(height, width))
実行結果を確認すると、calc.pyで出力している6も表示されてしまいます。

この原因は、実行するたびに、calc.pyのprint文が実行されるためです。
この問題を解決するために、特殊属性__name__を使用します。

__name__ とは、Pythonのコードを実行するときに自動的に作られる変数の1つで、実行しているプログラムのモジュール名が格納されています。
そのため、モジュールインポートする際に、モジュール名を識別する際に使用することができます。
メインモジュールとは、直接実行したモジュールのことを指します。
演習で、__name__属性に何が格納されているか確認してみます。
calc.py
def calc_area(x, y):
return x * y
x = 2
y = 3
print(calc_area(x, y))
3-02.py
import calc
print(calc.__name__)
print(__name__)
実行結果より、インポートしたcalcモジュールの__name__属性の値は、calcとなっていることが確認できました。
それから、実行したスクリプト(3-02.py)の__name__属性の値は、__main__となっていることが分かりました。

先ほどの演習に対して、calc.pyに__name__属性を表示する処理を追加して、3-02.pyを実行、calc.pyを実行した場合の出力の違いを確認してみます。

このように、実行スクリプトとなる場合、__name__属性の値には、__main__と格納されていることが確認できました。
そのため、モジュールのデバッグを行う場合に、値を表示させる、のような場合に使用することもできます。
次の演習では、calc.pyでprint文が実行されてしまう問題を解決するためには、__name__属性の値が__main__の時だけprint文を実行するようにします。
calc2.py
def calc_area(x, y):
return x * y
x = 2
y = 3
if __name__ == '__main__':
print(calc_area(x, y))
3-03.py
import calc2
print(calc2.x)
height, width = 3, 5
print(calc2.calc_area(height, width))
calc2モジュールのprint文は実行されないようになりました!

__pycache__フォルダ
今回の演習のように、自分でモジュールを作成し、importして実行していると、そのフォルダ配下に、「__pycache__」というフォルダが自動的に作成されます。
このフォルダには、モジュールをコンパイルしたキャッシュを保管され、次回以降スクリプトを実行する際に、作成済のキャッシュを読み込むことで、処理を早くする、というメリットがあるそうです。
モジュールのインポート方法
モジュールのインポートの方法には、いくつか方法があります。
モジュールを名前を変えてインポート

インポートするモジュールの名前が長い場合などに使用されるインポートの方法です。
インポートしたモジュールをスクリプト内で使用する場合、as 以降に定義した名前で使用することができます。
モジュールから直接インポート

モジュールの中から特定の識別子、例えば、関数、変数、クラスなどを使用するインポートの方法です。
メリットは、コードの記述がとても短くなります。
デメリットとしては、同じ名前の識別子が別のモジュールにあったり、スクリプト内にある場合に、バッティングしてしまいますので、注意が必要です。
組み込みモジュール

インポートするだけで使用したいモジュールをすぐに活用できます。

公式サイトに記載されていますので、ご参照ください。
2.パッケージ
パッケージとは?

パッケージを作るには?

ディレクトリを作成し、その配下に、__init__.pyファイルを配置します。
__init__.pyファイルの役割は、パッケージであることの目印、パッケージの初期化、パッケージの制御、パッケージ内の設定などがあります。
__init__.pyのファイルの中身は、なにも記述しないで問題なく、このことで「パッケージであることの目印」の役割を果たします。
パッケージ内のモジュールのインポート

パッケージ内の特定のモジュールをインポートしたい場合、下記のように変更することができます。
ディレクトリ構成は下記です。
root
├ 3-08.py
└ pack
├ __init__.py
└ calc3.py
3-08.py
from pack import calc3
print(calc3.x)
height, width = 3, 5
print(calc3.calc_area(height, width))
パッケージの __init__.py は、実行スクリプトからパッケージが最初に呼び出された時に1回だけ実行されます。
パッケージ例

pandasのパッケージ構成を、GitHubで見てみます。
pandasディレクトリをクリックします。

ディレクトリ配下に、__init__.pyファイルがあり、その他ディレクトリが配置されていることが確認できました。

ここまでの内容、モジュール、パッケージ、標準・外部ライブラリについて、図で説明してくださっているツイートです。わかりやすいです!
Pythonのライブラリ、パッケージ、モジュール、クラス、関数についてまとめました。図にすると分かりやすいですね🌟 pic.twitter.com/6Ke2fQTK8V
— みやさかしんや@Python/DX/エンジニア (@miyashin_prg) March 30, 2022
3.datetimeモジュール
最もよく使用する組み込みモジュールの1つ、datetimeモジュール。
datetimeモジュール

日時に関するデータを取り扱う際に使用します。
datetimeモジュールのクラス

この2つ以外にも、日付を表すdateクラス、時刻を表すtimeクラスなどがあります。
datetimeモジュールのインポート

ネット上のコードを見ると、これ以外にもimportの仕方はいろいろあります。
個人的には、このfromキーワードを使ったimportの仕方がコードがわかりやすいと思っています。
datetimeオブジェクトのコンストラクタ

パラメータのうち、year、month、dayは必須で設定する必要があります。それ以外のパラメータは省略した場合、0が設定されます。
なお、コンストラクタで設定するそれぞれのパラメータの値には、範囲が設定されて値ます。
範囲外の場合、例外ValueErrorが送出されます。
datetimeクラスの属性

nowは、クラスメソッドです。インスタンスメソッドではないのは、datetimeクラス全体で現在時刻を取得するためかと思われます。
weekday,strftimeは、インスタンスメソッドです。
strftimeメソッドと書式コード
strftimeメソッドは、datetimeクラスの日付/時刻のデータを指定された書式に従って文字列に変換するメソッドです。

これ以外の書式コードは、公式ドキュメントに記載されています。
日付を比較する

datetimeオブジェクトを使って日付を比較するには、比較演算子の<、>を使用することができます。
timedeltaクラスのインポート

timedeltaクラスを使うことで、日付の加算減算をすることができます。
モジュールのインポートの仕方のうち、モジュールから直接インポートするを使ってます。
timedeltaクラスのコンストラクタ

パラメータはすべてオプション付きで、デフォルトが0となります。
timedeltaクラスの属性

属性は、日、秒、マイクロ秒の3つです。ということは、月、年の加算減算はサポートしていません。
月、年の加算減算をしたい場合、サードパーティ製のライブラリrelativedeltaを使用することができます。
日付の加算・減算

dtは、datetimeオブジェクト、tdは、timedeltaオブジェクトです。
○日後、△日前の、○や△をtimedeltaオブジェクトで指定することになります。
日時の差を求める

日時の差を求める場合、dtは、datetimeオブジェクトを指定し、戻り値が、timedeltaオブジェクトで取得できます。
講座ツイートまとめ
講座では、記憶定着化のため、アウトプットすることが推奨されています。受講された皆様方のツイートまとめは、下記よりご参照ください。
まとめ
今回は、ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第3回「モジュール」について、講座内容と学習のメモまとめました。
次回はいよいよ最終回、第4回「ファイル操作とAPI」です。
目次
1.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第1回 「関数と式」学習メモ
2.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第2回 「オブジェクトとクラス」学習メモ
3.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第3回 「モジュール」学習メモ
4.ノンプロ研 中級プログラミング講座【Pythonコース】第1期 第4回 「ファイル操作とAPI」学習メモ