【Python入門】16章の演習プログラム

 16章では、Pythonのオブジェクト指向をより深く理解するために、ダックタイピングと抽象クラス、特殊メソッド、デコレーター、そして属性の仕組みを学習しました。ここでは、その内容を総合的に復習できる演習プログラムを作成し、さらに自分のコードを改善・拡張するきっかけにしていきます。どれもPythonを本格的に扱う上で重要なトピックなので、ぜひ手を動かして身につけましょう。

プログラムのダウンロード

 「ダウンロード」から実行できるサンプルプログラムがダウンロードできます。ファイルは、ESET Endpoint Securityでウイルスチェックをしておりますが、ダウンロードとプログラムの実行は自己責任でお願いいたします。

1.ダックタイピングと抽象クラス

  • ダックタイピング: 「アヒルのように鳴けばアヒル」という考え方をプログラムに適用し、オブジェクトが備えるメソッド名や属性に基づいて動作を決める方法です。クラス名に頼らない柔軟な設計ができる利点があります。
  • 抽象クラス(ABC): インスタンス化を許さないクラスを定義し、抽象メソッドによって派生クラスが必ず実装しなければならないメソッドを強制できます。設計段階での契約を明確にし、大規模なコードでの保守と拡張を容易にします。

2.特殊メソッドの定義

 「__str__」や「__add__」など、アンダースコア2つで囲まれたメソッドを定義すると、print()の結果や演算子の動作をカスタマイズできます。Pythonの「演算子オーバーロード」ともいえる仕組みで、クラスを自然に扱えるようになります。

3.デコレーターの利用

  • @property: インスタンス変数を読み書きするときにメソッドを介し、バリデーションや自動計算を行う仕組みを提供。
  • @staticmethod: インスタンスを使わない、クラス内ユーティリティ関数を定義するときに使う。
  • @classmethod: クラス自体を引数に受け取り、クラス全体に依存した処理を行う。クラスのアップデートなどが容易になる。

4.属性の仕組み

  • 組み込み関数setattr, getattr, hasattr, delattr、加えてdirvarsを使うと、オブジェクトが動的に持つ属性を制御したり、外部から属性の一覧を調べられる。
  • __slots__: オブジェクトが新たに持てる属性を限定し、不要な属性追加を防いだりメモリ効率を向上させられる。

サンプルプログラム: 総合演習

 以下のプログラムは、ダックタイピングと抽象クラスを組み合わせたデモです。さまざまな特殊メソッド、デコレーター、属性操作を取り入れています。細部を変更して、実行してみてください。

from abc import ABC, abstractmethod

class Animal(ABC):
    """抽象クラス:動物のインターフェースを定義。"""
    
    @abstractmethod
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "わんわん"

class Bird(Animal):
    def speak(self):
        return "ぴちゅん"

class SoundPrinter:
    """ダックタイピングで speak() があれば音を出すクラス."""
    
    def play_sound(self, entity):
        if hasattr(entity, 'speak'):
            print("サウンド:", entity.speak())
        else:
            print("speakメソッドがありません。")

class Info:
    """プロパティとスロットの例."""

    __slots__ = ['_data']  # dataという属性のみ持てるように制限
    
    def __init__(self, val):
        self._data = val
    
    @property
    def data(self):
        return self._data
    
    @data.setter
    def data(self, val):
        if val < 0:
            val = 0
        self._data = val

def main():
    print("◆ 総合演習デモ ◆")
    
    # 抽象クラスから派生したクラスをインスタンス化
    dog = Dog()
    bird = Bird()
    
    # ダックタイピング:speak()を持つオブジェクトに同じ処理
    sp = SoundPrinter()
    sp.play_sound(dog)   # サウンド: わんわん
    sp.play_sound(bird)  # サウンド: ぴちゅん
    sp.play_sound(123)   # speakメソッドがありません。
    
    # 属性制限とプロパティの例
    i = Info(10)
    print("最初の値:", i.data)  # 10
    i.data = 25
    print("更新後の値:", i.data) # 25
    i.data = -5  # 0に修正
    print("負の値が来ても0にする:", i.data)

if __name__ == "__main__":
    main()
    print("◆ デモ終了 ◆")

実行結果

◆ 総合演習デモ ◆
サウンド: わんわん
サウンド: ぴちゅん
speakメソッドがありません。
最初の値: 10
更新後の値: 25
負の値が来ても0にする: 0
◆ デモ終了 ◆

これでPython入門の章はすべて完了です。

 ここまでお疲れさまでした。Pythonはシンプルさと柔軟さを両立した言語であり、オブジェクト指向機能も「ダックタイピング」という独特の考え方で実装の幅を大きく広げています。さらに抽象クラスや特殊メソッド、デコレーターを組み合わせれば、オブジェクト指向設計をとても表現力豊かに書けることでしょう。
 さらなる学習では、Webフレームワークやデータサイエンス、機械学習など、多様な分野にPythonを応用できます。ぜひこのサイトを引き続き参考に、新たなテーマに挑戦してみてください!