😀

【Python】なんでabstractmethodだけimportするの?classmethodとの違い

に公開

今日は、Pythonの「abstractmethod」について、なぜこれだけインポートが必要なのかを説明します。

まず基本的な違いを見てみよう

Pythonには、メソッドを特別な形で使うための仕組みがいくつかあります。

classmethod と staticmethod(インポート不要)

class Sample:
    count = 0
    
    @classmethod  # インポートしなくても使える!
    def get_count(cls):
        return cls.count
    
    @staticmethod  # これもインポートしなくても使える!
    def add_numbers(a, b):
        return a + b

# 普通に使える
print(Sample.get_count())  # 0
print(Sample.add_numbers(5, 3))  # 8

abstractmethod(インポートが必要)

# これをしないとエラーになる!
from abc import ABC, abstractmethod

class Animal(ABC):
    @abstractmethod  # インポートしないと使えない
    def make_sound(self):
        pass

class Dog(Animal):
    def make_sound(self):
        return "ワンワン"

# dog = Dog()  # これは動く
# animal = Animal()  # これはエラー!

なぜ abstractmethod だけ特別なの?

理由1:Pythonに最初からある機能かどうか

classmethod と staticmethod

  • Pythonが生まれた時から持っている基本機能
  • Pythonの「心臓部」に組み込まれている
  • だからインポートしなくても使える

abstractmethod

  • 後から追加された機能
  • 別の場所(abcモジュール)に保管されている
  • 使いたい時は「取りに行く」必要がある

理由2:使う頻度の違い

# classmethod と staticmethod はよく使う
class Calculator:
    @classmethod
    def from_string(cls, text):
        return cls(int(text))
    
    @staticmethod
    def add(a, b):
        return a + b

# abstractmethod は特別な時だけ使う
from abc import ABC, abstractmethod

class Vehicle(ABC):  # 乗り物の設計図
    @abstractmethod
    def start_engine(self):  # エンジンを始動する(必ず実装してね)
        pass

理由3:目的の違い

classmethod と staticmethod

  • 普通のプログラムでよく使う
  • 「便利な道具」みたいなもの

abstractmethod

  • 「設計図」を作る時だけ使う
  • 「このメソッドは絶対に作ってね!」という約束事を決める

実際のコード例で比べてみよう

インポートなしで動くもの

class School:
    student_count = 0
    
    @classmethod
    def get_student_count(cls):
        return f"全校生徒は{cls.student_count}人です"
    
    @staticmethod
    def calculate_score(test1, test2):
        return (test1 + test2) / 2

# すぐに使える
print(School.get_student_count())
print(School.calculate_score(80, 90))

インポートが必要なもの

# これがないとエラー!
from abc import ABC, abstractmethod

class Game(ABC):
    @abstractmethod
    def start(self):
        """ゲームを始める(必ず実装してね)"""
        pass
    
    @abstractmethod
    def end(self):
        """ゲームを終わる(必ず実装してね)"""
        pass

class PacmanGame(Game):
    def start(self):
        return "パックマンゲーム開始!"
    
    def end(self):
        return "ゲーム終了。スコアを保存中..."

# pacman = PacmanGame()  # OK
# game = Game()  # エラー!抽象クラスは直接作れない

まとめ

  • classmethodstaticmethod は、Pythonの基本機能だからインポート不要
  • abstractmethod は、特別な機能だから from abc import abstractmethod が必要
  • abstractmethod は「設計図」を作る時の特別な道具
  • 普通のプログラムでは classmethod と staticmethod の方をよく使う

Discussion