モジュール
Pythonを学習する中で、私たちは
print()
、input()
、type()
などのあらかじめ定義されたPython関数を使ってきました。Pythonには多数の関数がありますが、そのすべてが新しいPythonスクリプトから直接アクセスできるわけではありません。代わりに、それらは モジュール
と呼ばれる別のファイルに保存されています。これらの関数を使うためには、それらを含むモジュールをインポートする必要があります。これは import
文を使って行います。例を見てみましょう:import math # mathモジュールをインポート
print(math.pi) # mathモジュールから定数piを取得
print(math.sqrt(16)) # mathモジュールの平方根関数を使用
このプログラムは、
pi
の値(3.141592653589793
)と 16
の平方根(4.0
)を出力します。また、
from
...import
文を使って、モジュールから特定の属性や関数をインポートすることもできます。from math import pi, sqrt # mathモジュールから pi と sqrt だけをインポート
print(pi) # モジュール名を付けずに pi を直接使用できます
print(sqrt(16)) # 同様に、sqrt も直接使用できます
このプログラムの出力も、前と同じになります。
モジュールによっては名前が長いことがあり、関数を使用するたびにその名前全体を入力するのは面倒な場合があります。そのため、
as
キーワードを使ってモジュールに別の名前(エイリアス)を割り当てることができます。import math as m # mathモジュールをインポートし、m として名前を付ける
print(m.pi) # これで短いエイリアスを使えます
print(m.sqrt(16)) # エイリアスを使って sqrt 関数を使用
出力も先ほどと同じく、
3.141592653589793
と 4.0
になります。まとめると、Pythonのモジュールはあらかじめ定義された関数や変数を含むツールボックスのようなものであり、それらをインポートしてプログラムで使用できます。モジュールはコードの整理や効率化に役立ちます。
モジュールの内部動作
モジュールをインポートすると、Pythonは表面には見えない内部的な処理を行います。
import
文を使ったときに何が起こるのか、概要を見てみましょう:- モジュールの検索:
Pythonはまず、自身の
sys.path
リストに指定された場所を調べてモジュールを探します。このリストにはカレントディレクトリ、組み込みのPythonパッケージディレクトリ、そして環境変数PYTHONPATH
に指定されたパスが含まれます。Pythonがモジュールを見つけると、次のステップに進みます。見つからない場合は、ModuleNotFoundError
を発生させます。
- モジュールの初期化:
モジュールファイルが見つかると、Pythonは新しいモジュールオブジェクト(
types.ModuleType
)を作成します。そして、そのモジュールの内容をこの新しいオブジェクトにロードし、モジュールファイル内のすべてのトップレベルコードを実行します。これには関数、クラス、変数の定義や初期化コードの実行が含まれます。
- モジュールのキャッシュ:
初期化後、モジュールは
sys.modules
(辞書型)にキャッシュされます。このステップにより、同じモジュールがスクリプト内(または他のスクリプトで)再度インポートされた場合、Pythonは再度モジュールを検索して初期化する必要がなくなります。代わりに、キャッシュされたバージョンを使用できます。この辞書のキーはモジュール名で、値はモジュールオブジェクトです。
- インポート元へのモジュール追加: 最後に、Pythonはモジュールの名前を、そのモジュールをインポートしたスクリプトやモジュールの名前空間に追加します。この名前はモジュールオブジェクトを参照するので、ドット表記を使ってモジュールの関数や変数にアクセスできます。
コードを使ってこれを説明してみましょう:
import sys
import math
print(sys.path) # Pythonがモジュールを探すパス
print(sys.modules) # キャッシュされたモジュール
print(math.sqrt(16)) # mathモジュールの関数を使用
sys.path
は、Pythonがモジュールを検索するディレクトリのリストを出力します。sys.modules
は、モジュール名(キー)とそれぞれのモジュールオブジェクト(値)の辞書を出力します。 チャレンジ:乱数
暗号の世界では、乱数は非常に重要な役割を果たします。暗号アルゴリズムは、データを安全に保つために、しばしば乱数の列を生成することに依存しています。
このチャレンジでは、乱数をより具体的に理解するための簡単な乱数ジェネレーターをシミュレートすることが課題です。Pythonには乱数を生成するためのさまざまな関数を持つ組み込みモジュール
random
があります。このモジュールを使って、指定された2つの数 a
と b
の間の n
個のランダムな整数のリストを生成してください。ただし、乱数は真の乱数である必要はなく、実験の再現性のためにシードを 42
に固定する必要があります。シードを固定するには seed()
関数を使い、乱数を生成するには randint()
を使うことができます。入力の最初の行には、スペースで区切られた3つの整数
n
、a
、b
が含まれます。数値 a
と b
は、乱数を選ぶ範囲(両端を含む)を決定し、n
は生成する必要がある数の個数を決定します。プログラムは、ランダムシードを
42
に固定し、範囲 [a, b]
内で生成された n
個の乱数をスペースで区切って出力する必要があります。入力 | 出力 |
10 1 100 | 82 15 4 95 36 32 29 18 95 14 |
5 1 5 | 1 1 3 2 2 |
3 10 20 | 20 11 10 |
注意: ランダムシードを
42
に設定しているため、プログラムの出力の順序は複数回実行しても同じになります。これは、テストやデバッグなどの状況で決定的な出力が必要なときに利用する特徴です。Constraints
Time limit: 2 seconds
Memory limit: 512 MB
Output limit: 1 MB