Python入門で気をつけるポイント(3)モジュールについて

Python入門で気をつけるポイント(3)モジュールについて

モジュール

Pythonインタープリンタは一度終了すると、終了するまでの関数や変数は全て失われます。
そのため長いプログラムはテキストエディタで作成して「.py」ファイルにしておくと良いです。
Pythonではこのファイル(.py)のことをモジュールと呼んでいます。
Pythonの対話モードはmainモジュールと呼んでいます。

各モジュールはimportで別のモジュールで読み込むことができます。
モジュールにはグローバル変数として__name__の値としてモジュール名が自動的に設定されます。

以下のコードをテキストエディタで書いて「hello.py」で保存します。

hello = 'Hello,world!'
print(hello)

ファイルを保存した場所にcdで移動したのち以下のコマンドをターミナルに入力してみましょう。
python3またはpythonでPythonの対話モードに入ります。
1、import helloでhello.pyを読み込みます。
2、__name__でモジュール名を確認してみます。
3、hello.__name__でモジュール名を確認してみます。
python3
>>> import hello
Hello,world!
>>> __name__
'__main__'
>>> hello.__name__
'hello'

mainモジュールでは__main__と出てきます。
helloモジュールを読み込むにはhello.__name__のようにします。
そうすると’hello’という答えが返ってきます。

フィボナッチ級数の関数をモジュール化します。
ファイル名は「fibo.py」で保存します。

def fib(n):    # write Fibonacci series up to n
    a, b = 0, 1
    while a < n:
        print(a, end=' ')
        a, b = b, a+b
    print()

def fib2(n):   # return Fibonacci series up to n
    result = []
    a, b = 0, 1
    while a < n:
        result.append(a)
        a, b = b, a+b
    return result

次にPython対話モードで以下を実行します。
関数の命令文の通りフィボナッチ級数が表示されます。

>>> import fibo
>>> fibo.fib(1000)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610 987 
>>> fibo.fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

from import文

from import文でモジュールを読み込むともっと簡単に関数が使えます。
関数の前にオブジェクト名をつける必要が無くなります。

>>> from fibo import fib, fib2
>>> fib(500)
0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 
>>> fib2(500)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 144, 233, 377]

注意点として、モジュール名自体はローカルシンボル表に読み込まれてない。
例えば次のようになる。

>>> from fibo import fib
>>> fib(100)
0 1 1 2 3 5 8 13 21 34 55 89 
>>> fibo.fib2(100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'fibo' is not defined
>>> fib2(100)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'fib2' is not defined

from fibo import fibとした場合、当然fib2(100)ではエラーになる。
fibo.fib2(100)としてもエラーになります。

なお、「from fibo import *」とすると全ての関数を読み込むことができます。
けれども、これは可読性が落ちる場合がありますので一般的には使わないようにしましょう。

>>> from fibo import *
>>> fib(100)
0 1 1 2 3 5 8 13 21 34 55 89 
>>> fib2(100)
[0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89]

コンパイル済みPythonファイル

モジュール読み込みの高速化のためにコンパイル済みのモジュールを「__pycache__」に保存します。通常これらのファイルは気にする必要はありませんが、モジュールを保存したフォルダに自動で作られますので知っておくと良いでしょう。

dir関数

dir関数はモジュールを定義している関数などを確認することができます。

>>> import fibo
>>> dir(fibo)
['__builtins__', '__cached__', '__doc__', '__file__', '__loader__', '__name__', '__package__', '__spec__', 'fib', 'fib2']

パッケージ

パッケージについて、Pythonチュートリアルでは次のように説明しています。
「パッケージとはドット区切りモジュール名を使ってPythonモジュールを駆逐する方法」
はあ?
ざっくりいうと次のようなことになります。
モジュール = Python ファイルのことで、拡張子は「 .py」となっています 。
パッケージ = ディレクトリのことで、そのディレクトリには「 __init__.py 」というファイルを含んでいます。

我々はグラフを描くときにpyplotモジュールを読み込むのですが、通常pyplotモジュールを読み込む場合次のようにするはずです。

import matplotlib.pyplot as plt

as pltはpyplotモジュールを省略してpltにしたものです。
通常このasの使い方の説明はよく出てくるのですが、「matplotlib.pyplot」の書き方については触れられていません。
「import numpy as np」ではnumpyというモジュール名で読み込まれているのになぜ?
これは、「matplotlib.pyplot」はmatplotlibパッケージのpyplotモジュールという呼び出し方を行なっているからです。