Python モジュールの定義とインポート

Beginner

This tutorial is from open-source community. Access the source code

はじめに

この実験では、Python モジュールについて学びます。Python モジュールとは、他のプログラムでインポートして使用できる Python コードを含むファイルのことです。このモジュール化されたアプローチはコードの再利用を促進し、プログラムを論理的なコンポーネントに整理するのに役立ちます。

Python モジュールが何であるか、なぜ有用なのかを理解し、独自のモジュールを作成する方法を学び、さまざまな方法で import 文を使用する練習を行い、メインモジュールの概念とコードが実行されるタイミングを理解します。前提条件として、Python の構文と関数の基本的な理解、および Python スクリプトの作成と実行に慣れていることが必要です。この演習を開始する前に、クリーンな環境を得るために Python インタープリターのセッションを再起動することをお勧めします。

これは Guided Lab です。学習と実践を支援するためのステップバイステップの指示を提供します。各ステップを完了し、実践的な経験を積むために、指示に注意深く従ってください。過去のデータによると、この 初級 レベルの実験の完了率は 97%です。学習者から 100% の好評価を得ています。

Python モジュールの理解

Python では、モジュールは Python の定義や文を格納するコンテナのようなものです。実質的にはファイルであり、このファイルの名前がモジュール名で、末尾に .py 拡張子が付きます。モジュールをツールボックスのように考えてください。モジュールは Python コードを論理的に整理するのに役立ち、再利用やメンテナンスを容易にします。整理を良くするために異なるツールを別々のボックスに入れるように、関連する Python コードを異なるモジュールにグループ化することができます。

この実験で設定されたファイルを見てみましょう。

  1. まず、エディタで stock.py ファイルを開き、中身を確認します。これを行うには、以下のコマンドを使用します。cd コマンドはディレクトリをファイルがある project フォルダに変更し、cat コマンドはファイルの内容を表示します。
cd ~/project
cat stock.py

この stock.py ファイルは Stock クラスを定義しています。クラスはオブジェクトを作成するための青写真のようなものです。この場合、Stock クラスは株式を表します。株式の名前、株数、価格に関する属性(特性のようなもの)があります。また、株式のコストを計算するメソッド(クラスに関連付けられた関数のようなもの)もあります。

  1. 次に、pcost.py ファイルを調べましょう。再び cat コマンドを使用してその内容を表示します。
cat pcost.py

このファイルは portfolio_cost() という関数を定義しています。関数は特定のタスクを実行するコードのブロックです。portfolio_cost() 関数はポートフォリオファイルを読み込み、そのポートフォリオに含まれるすべての株式の総コストを計算します。

  1. では、サンプルのポートフォリオデータを見てみましょう。cat コマンドを使用して portfolio.dat ファイルの内容を表示します。
cat portfolio.dat

このファイルには、簡単な形式で株式データが含まれています。各行には株式のティッカーシンボル、株数、1 株あたりの価格が記載されています。

import 文の使用

Python の import 文は、他のモジュールのコードを現在のプログラムで使用できるようにする強力なツールです。他のツールボックスからツールを借りるようなものです。コードをインポートするさまざまな方法を練習してみましょう。

  1. まず、Python インタープリターを起動する必要があります。Python インタープリターは Python コードを実行するプログラムです。以下のコマンドを使用して起動します。
python3
  1. では、pcost モジュールをインポートして、何が起こるか見てみましょう。import 文を使用すると、Python は pcost.py ファイルを探し、その中のコードを使用できるようにします。
import pcost

出力として 44671.15 が表示されるはずです。これは portfolio.dat ファイルから計算されたポートフォリオのコストです。pcost モジュールがインポートされると、pcost.py ファイルの末尾のコードが自動的に実行されます。

  1. 異なるポートフォリオファイルで portfolio_cost() 関数を呼び出してみましょう。pcost.portfolio_cost() 構文を使用して、pcost モジュールから関数を呼び出します。
pcost.portfolio_cost('portfolio2.dat')

出力は 19908.75 であるはずで、これは 2 番目のポートフォリオファイルに含まれる株式の総コストを表しています。

  1. では、stock モジュールから特定のクラスをインポートしてみましょう。モジュール全体をインポートする代わりに、from...import 文を使用して Stock クラスだけをインポートすることができます。
from stock import Stock
  1. Stock クラスをインポートした後、Stock オブジェクトを作成することができます。オブジェクトはクラスのインスタンスです。名前が GOOG、株数が 100、価格が 490.10Stock オブジェクトを作成します。そして、株式の名前を表示し、cost() メソッドを使用してそのコストを計算します。
s = Stock('GOOG', 100, 490.10)
print(s.name)
print(s.cost())

出力は以下のようになるはずです。

GOOG
49010.0
  1. 最後に、Python インタープリターの使用が終わったら、exit() 関数を使用して終了することができます。
exit()

この実験では、Python コードをインポートする 2 つの異なる方法を示しました。

  • import module_name - これはモジュール全体をインポートし、そのモジュール内のすべての関数、クラス、変数を使用できるようにします。
  • from module_name import specific_item - これはモジュールから特定のアイテム(クラスや関数など)のみをインポートします。モジュールの機能の一部だけが必要な場合に便利です。

Python でのメインモジュールの理解

Python では、スクリプトを直接実行すると、それが「メイン」モジュールとして機能します。Python には __name__ という特別な変数があります。ファイルが直接実行されると、Python は __name__ の値を "__main__" に設定します。これは、ファイルがモジュールとしてインポートされる場合とは異なります。

この機能は非常に便利です。なぜなら、ファイルが直接実行されるか、インポートされるかに応じて異なる動作をするコードを書くことができるからです。たとえば、あるコードをスクリプトとしてファイルを実行したときにのみ実行し、他のスクリプトによってインポートされたときには実行しないようにしたい場合があります。

pcost.py をメインモジュールパターンを利用するように変更する

このパターンを利用するために、pcost.py プログラムを変更しましょう。

  1. まず、エディタで pcost.py ファイルを開く必要があります。以下のコマンドを使用してプロジェクトディレクトリに移動し、ファイルが存在しない場合は作成することができます。
cd ~/project
touch pcost.py

cd コマンドは現在のディレクトリをホームディレクトリ内の project ディレクトリに変更します。touch コマンドは pcost.py という名前の新しいファイルが存在しない場合に作成します。

  1. 次に、pcost.py ファイルを以下のように変更します。
## pcost.py

def portfolio_cost(filename):
    total_cost = 0.0

    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            try:
                nshares = int(fields[1])
                price = float(fields[2])
                total_cost += nshares * price
            except (ValueError, IndexError):
                print(f"Couldn't parse: {line}")

    return total_cost

## このコードはファイルがスクリプトとして実行されたときにのみ実行されます
if __name__ == "__main__":
    total = portfolio_cost('portfolio.dat')
    print(total)

主な変更点は、末尾のコードを if __name__ == "__main__": の条件文で囲んだことです。これは、このブロック内のコードがファイルがスクリプトとして直接実行されたときにのみ実行され、モジュールとしてインポートされたときには実行されないことを意味します。

  1. これらの変更を加えた後、ファイルを保存してエディタを終了します。

変更後のモジュールのテスト

では、変更後のモジュールを 2 つの異なる方法でテストし、その動作を確認しましょう。

  1. まず、以下のコマンドを使用してプログラムをスクリプトとして直接実行します。
python3 pcost.py

以前と同じように、出力として 44671.15 が表示されるはずです。これは、スクリプトを直接実行すると、__name__ 変数が "__main__" に設定されるため、if __name__ == "__main__": ブロック内のコードが実行されるからです。

  1. 次に、再び Python インタープリターを起動し、モジュールをインポートします。
python3
import pcost

今回は何も出力が表示されません。モジュールをインポートすると、__name__ 変数は "pcost"(モジュール名)に設定され、"__main__" ではなくなります。したがって、if __name__ == "__main__": ブロック内のコードは実行されません。

  1. portfolio_cost 関数がまだ機能していることを確認するには、以下のように呼び出すことができます。
pcost.portfolio_cost('portfolio.dat')

この関数は 44671.15 を返すはずで、これは関数が正常に動作していることを意味します。

  1. 最後に、以下のコマンドを使用して Python インタープリターを終了します。
exit()

このパターンは、インポート可能なモジュールとしても、スタンドアロンのスクリプトとしても使用できる Python ファイルを作成する際に非常に便利です。if __name__ == "__main__": ブロック内のコードは、ファイルが直接実行されたときにのみ実行され、モジュールとしてインポートされたときには実行されません。

独自のモジュールの作成

既存のモジュールの使い方がわかったところで、新しいモジュールをゼロから作成しましょう。Python のモジュールは、Python の定義や文を含むファイルです。これにより、コードを再利用可能で管理しやすいピースに整理することができます。独自のモジュールを作成することで、関連する関数や変数をまとめることができ、コードをよりモジュール化し、メンテナンスしやすくすることができます。

レポートモジュールの作成

株式レポートを生成するための簡単なモジュールを作成しましょう。このモジュールには、ポートフォリオファイルを読み込み、ポートフォリオ内の株式の整形されたレポートを印刷する関数が含まれます。

  1. まず、report.py という名前の新しいファイルを作成する必要があります。これを行うには、コマンドラインを使用します。ホームディレクトリ内の project ディレクトリに移動し、touch コマンドを使用してファイルを作成します。
cd ~/project
touch report.py
  1. 次に、好みのテキストエディタで report.py ファイルを開き、以下のコードを追加します。このコードは 2 つの関数とメインブロックを定義しています。
## report.py

def read_portfolio(filename):
    """
    Read a stock portfolio file into a list of dictionaries with
    keys: name, shares, price
    """
    portfolio = []
    with open(filename, 'r') as f:
        for line in f:
            fields = line.split()
            try:
                stock = {
                    'name': fields[0],
                    'shares': int(fields[1]),
                    'price': float(fields[2])
                }
                portfolio.append(stock)
            except (ValueError, IndexError):
                print(f"Couldn't parse: {line}")
    return portfolio

def print_report(portfolio):
    """
    Print a report showing the stock name, shares, price, and total value
    """
    print("Name    Shares    Price    Value")
    print("-" * 40)
    total_value = 0.0
    for stock in portfolio:
        value = stock['shares'] * stock['price']
        total_value += value
        print(f"{stock['name']:6s} {stock['shares']:9d} {stock['price']:9.2f} {value:9.2f}")
    print("-" * 40)
    print(f"Total Value: {total_value:16.2f}")

if __name__ == "__main__":
    portfolio = read_portfolio('portfolio.dat')
    print_report(portfolio)

read_portfolio 関数は、株式情報を含むファイルを読み込み、辞書のリストを返します。各辞書は、namesharesprice をキーとする株式を表します。print_report 関数は、ポートフォリオ(株式辞書のリスト)を受け取り、株式名、株数、価格、および総価値を示す整形されたレポートを印刷します。末尾のメインブロックは、ファイルが直接実行されたときに実行されます。ポートフォリオファイルを読み込み、レポートを印刷します。

  1. コードを追加した後、ファイルを保存してエディタを終了します。

モジュールのテスト

新しいモジュールが期待通りに動作することを確認するために、テストを行いましょう。

  1. まず、コマンドラインからスクリプトを直接実行します。これにより、report.py ファイル内のメインブロックが実行されます。
python3 report.py

ポートフォリオ内の株式とその価値を示す整形されたレポートが表示されるはずです。このレポートには、株式名、株数、価格、総価値、およびポートフォリオ全体の総価値が含まれます。

Name    Shares    Price    Value
----------------------------------------
AA         100     32.20   3220.00
IBM         50     91.10   4555.00
CAT        150     83.44  12516.00
MSFT       200     51.23  10246.00
GE          95     40.37   3835.15
MSFT        50     65.10   3255.00
IBM        100     70.44   7044.00
----------------------------------------
Total Value:         44671.15
  1. 次に、Python インタープリターからモジュールを使用します。ターミナルで python3 コマンドを実行して、Python インタープリターを起動します。
python3

インタープリターが起動したら、report モジュールをインポートし、その関数を使用することができます。

import report
portfolio = report.read_portfolio('portfolio.dat')
len(portfolio)  ## Should return 7, the number of stocks
portfolio[0]    ## First stock in the portfolio

import report 文により、report.py ファイルで定義された関数や変数が現在の Python セッションで使用可能になります。次に、read_portfolio 関数を使用してポートフォリオファイルを読み込み、結果を portfolio 変数に格納します。len(portfolio) 文はポートフォリオ内の株式の数を返し、portfolio[0] はポートフォリオ内の最初の株式を返します。

以下の出力が表示されるはずです。

7
{'name': 'AA', 'shares': 100, 'price': 32.2}
  1. では、インポートしたモジュールを使用して、自分でポートフォリオの総コストを計算しましょう。ポートフォリオ内の株式を繰り返し処理し、各株式の総価値を合計します。
total = 0.0
for stock in portfolio:
    total += stock['shares'] * stock['price']
print(total)

出力は 44671.15 であるはずで、これは print_report 関数によって印刷される総価値と同じです。

  1. 最後に、特定の株式タイプに対するカスタムレポートを作成しましょう。ポートフォリオをフィルタリングして、IBM の株式のみを含め、print_report 関数を使用してそれらの株式のレポートを印刷します。
ibm_stocks = [stock for stock in portfolio if stock['name'] == 'IBM']
report.print_report(ibm_stocks)

これにより、IBM の株式とその価値のみを示すレポートが印刷されるはずです。

Name    Shares    Price    Value
----------------------------------------
IBM         50     91.10   4555.00
IBM        100     70.44   7044.00
----------------------------------------
Total Value:         11599.00
  1. テストが終了したら、exit() コマンドを実行して Python インタープリターを終了します。
exit()

これで、独自の Python モジュールを作成し、使用することに成功しました。関数と、ファイルが直接実行されたときにのみ実行されるメインブロックの両方を組み合わせています。このようなモジュール化されたプログラミングアプローチにより、コードを再利用し、プロジェクトをより整理された状態でメンテナンスしやすくすることができます。

まとめ

この実験では、Python モジュールの基本概念と、コードの整理にどのように利用するかを学びました。モジュールは再利用可能なコードを含む Python ファイルであり、import 文を使用することで、他のモジュールのコードを自分のプログラムで利用することができます。if __name__ == "__main__" パターンを使用すると、ファイルをインポート可能なモジュールとしても、スタンドアロンのスクリプトとしても機能させることができます。

これらの概念は、特に大規模なアプリケーションを開発する際に、メンテナンス可能な Python コードを書くために重要です。Python の学習を続ける際には、モジュールが関連するコードをまとめるのに役立ち、特定のアイテムをインポートすることで名前空間をきれいに保つことができ、メインモジュールパターンはベストプラクティスであることを覚えておいてください。これらの技術を適用することで、コードをより整理された状態で、メンテナンスしやすく、再利用可能にすることができます。