Python のクラスとオブジェクト: 実際の例を含む OOP チュートリアル

  1. ホーム
  2. ブログ
  3. ソフトウェア開発

ソフトウェア開発

Python のクラスとオブジェクト: 実際の例を含む OOP チュートリアル

実際のものを構築することでオブジェクト指向 Python を学びます。クラスを作成し、self と __init__ を理解し、継承で動作を共有し、プロパティでデータを保護し、クラスが間違ったツールであることを認識します。

読了目安10分
Python のクラスとオブジェクト: 実際の例を含む OOP チュートリアル

ポイント

  • クラスはブループリントであり、オブジェクトはそれから構築される 1 つのものです。
  • __init__ は新しいオブジェクトをそれぞれ設定し、self はそのオブジェクトを参照します。
  • クラスに設定された属性は共有されます。 selfに設定された属性は 1 つのオブジェクトに属します。
  • データ保持クラスには @dataclass を使用し、保持する状態がない場合は単純な関数を好みます。

スクリプトが大きくなるにつれて、関数間で同じ変数グループを渡すことになり、どのデータがどのロジックに属しているかを区別することが難しくなります。 Python のクラスとオブジェクトは、データと動作を 1 つのユニットにバンドルすることでこの問題を解決します。

このチュートリアルでは、小規模な銀行口座を段階的に構築し、問題が解決した場合にのみ各 OOP アイデアを追加します。すべての例を Python 3.13 で実行し、示されている出力はその実行からのものです。この言語を初めて使用する場合は、まず 初心者向けの Python チュートリアルを読んでください。

クラスとオブジェクトとは何ですか?

クラスは、何かが何であるか、そしてそれが何ができるかを記述します。 オブジェクトはインスタンスとも呼ばれ、その記述から作成された特定のものです。 「アカウント」はクラスですが、Asha のアカウントと Ben のアカウントは 2 つのオブジェクトです。

期間 意味 例
クラス 青写真 アカウント
オブジェクトまたはインスタンス そこから作られたひとつの物 a = アカウント(「アシャ」)
属性 オブジェクトのデータ a.balance
方法 クラス上の関数 a.deposit(50)

あなたはずっとオブジェクトを使ってきました。 Python では、文字列、リスト、さらには関数さえもオブジェクトなので、"hello".upper() と書くことができます。

初めてのクラス

class Account:
    def __init__(self, owner, balance=0):
        self.owner = owner
        self.balance = balance

    def deposit(self, amount):
        if amount <= 0:
            raise ValueError("amount must be positive")
        self.balance += amount
        return self.balance

a = Account("Asha", 100)
b = Account("Ben")

a.deposit(50)
print(a.balance, b.balance)

# 150 0

__init__ はオブジェクトを作成するたびに自動的に実行され、開始状態を設定します。各オブジェクトには独自のデータがあるため、a へのデポジットは b には影響しませんでした。このメソッドは、残高を不正な値から保護することにも注意してください。 Python 例外処理 のガイドでは、raise についてさらに詳しく説明しています。

自己とは何ですか?

self は単にメソッドが処理しているオブジェクトです。 a.deposit(50) を記述すると、Python は効果的に Account.deposit(a, 50) を呼び出し、最初の引数としてオブジェクトを渡します。これにより、1 つのメソッド定義がすべてのオブジェクトにサービスを提供できるようになります。

名前 self はキーワードというよりも強力な規則ですが、常に使用してください。メソッド定義での引数の忘れは、最も一般的な初心者向けのエラーであり、引数の数に関するわかりにくいメッセージが生成されます。

クラス属性とインスタンス属性

クラス本体に直接設定された属性は、すべてのオブジェクトで共有されます。 self に設定された 1 つは、そのオブジェクトのみに属します。この例は、ルックアップがどのように動作するかを示しています。

class Account:
    interest_rate = 0.04    # class attribute

    def __init__(self, owner, balance=0):
        self.owner = owner  # instance attribute
        self.balance = balance

a = Account("Asha", 100)
b = Account("Ben")
print(a.interest_rate, b.interest_rate)   # 0.04 0.04

Account.interest_rate = 0.05
print(a.interest_rate, b.interest_rate)   # 0.05 0.05

a.interest_rate = 0.09
print(a.interest_rate, b.interest_rate, Account.interest_rate)
# 0.09 0.05 0.05

その最後の一行は人々を驚かせます。 a による割り当てでは共有値は変更されませんでした。 a にクラス 1 を非表示にする新しいインスタンス属性を作成しました。 Python は最初にオブジェクトを調べ、次にクラスを調べます。

特別な (ダンダー) メソッド

二重アンダースコアを含むメソッドを使用すると、オブジェクトが Python の組み込み機能で動作できるようになります。これらがないと、アカウントを印刷すると無駄なメモリ アドレスが表示されます。 2 つを追加すると、読みやすい形式になります。

    def __str__(self):
        return f"{self.owner}: {self.balance}"

    def __repr__(self):
        return f"Account({self.owner!r}, {self.balance})"

print(a)        # Asha: 150
print([a, b])   # [Account('Asha', 150), Account('Ben', 0)]
方法 きっかけは
__init__ オブジェクトの作成
__str__ print(obj), str(obj)
__repr__ デバッグまたはリストでの表示
__eq__ a == b
__len__ len(obj)
__add__ a + b

相続

継承により、新しいクラスは既存のクラスを再利用し、異なる部分のみを変更できます。ここで、Savings は追加の設定を備えた Account です。

class Savings(Account):
    def __init__(self, owner, balance=0, limit=3):
        super().__init__(owner, balance)
        self.limit = limit

    def __str__(self):
        return f"{super().__str__()} (savings)"

s = Savings("Chitra", 500)
s.deposit(100)
print(s, isinstance(s, Account), s.limit)

# Chitra: 600 (savings) True 3

super() は親のバージョンを呼び出すため、セットアップ ロジックは繰り返されません。 depositはそのまま継承し、__str__はオーバーライドしてラベルを追加しました。実際の「である」関係に対してのみ継承を使用してください。車がエンジンを必要とするなど、クラスが単に何かを必要とする場合は、そのオブジェクトを属性として与えます。これは合成として知られており、通常は深い継承チェーンよりも柔軟性が高くなります。

ポリモーフィズム

ポリモーフィズムとは、異なるオブジェクトが同じメソッド呼び出しに独自の方法で応答できることを意味します。呼び出し側のコードは正確な型を知る必要はありません。

class Square:
    def __init__(self, side):
        self.side = side
    def area(self):
        return self.side ** 2

class Circle:
    def __init__(self, radius):
        self.radius = radius
    def area(self):
        return round(3.14159 * self.radius ** 2, 2)

for shape in [Square(3), Circle(2)]:
    print(type(shape).__name__, shape.area())

# Square 9
# Circle 12.57

これら 2 つのクラスは親さえ共有しません。 Python は、オブジェクトに area メソッド、ダック タイピング として知られるアプローチがあることのみを考慮します。後で Triangle を追加しても、ループを変更する必要はありません。

カプセル化とプロパティ

Python には真のプライベート属性はなく、代わりに規約に依存します。 _price のような 1 つのアンダースコアは、他の開発者に「これは内部的なものなので触れないでください」と伝えます。設定時に値を確認するには、プロパティを使用します。これは、外側からはプレーンな属性のように見えます。

class Product:
    def __init__(self, price):
        self.price = price

    @property
    def price(self):
        return self._price

    @price.setter
    def price(self, value):
        if value < 0:
            raise ValueError("price cannot be negative")
        self._price = value

p = Product(100)
p.price = 150
print(p.price)      # 150
p.price = -5        # ValueError: price cannot be negative

これは、クラスを使用するコードを変更せずに、プレーンな属性から始めて、後で検証を追加できることを意味します。したがって、Java のように、習慣で get_price() および set_price() メソッドを作成しないでください。ここでの @ 構文はデコレータであり、Python デコレータの説明で説明します。

クラスメソッドと静的メソッド

class Temperature:
    def __init__(self, celsius):
        self.celsius = celsius

    @classmethod
    def from_fahrenheit(cls, f):
        return cls(round((f - 32) * 5 / 9, 1))

    @staticmethod
    def is_freezing(celsius):
        return celsius <= 0

Temperature.from_fahrenheit(212).celsius   # 100.0
Temperature.is_freezing(-3)                # True
種類 最初の引数 用途:
インスタンスメソッド 自分自身 1 つのオブジェクトのデータを操作する
@classmethod CLS 代替コンストラクター
@staticmethod なし クラスに関係するヘルパー

データクラス

クラスのほとんどがデータを保持している場合、__init__、__repr__、__eq__ を手作業で記述するのは面倒です。 @dataclass は型アノテーションからそれらを生成します。

from dataclasses import dataclass, field

@dataclass
class Item:
    name: str
    price: int
    tags: list = field(default_factory=list)

print(Item("Pen", 10))
print(Item("Pen", 10) == Item("Pen", 10))

# Item(name='Pen', price=10, tags=[])
# True

ヒント: すべてにクラスが必要なわけではありません。状態がなく、動作が 1 つだけの場合は、単純な関数の方が単純です。単純な検索の場合は、dictionary で十分な場合があります。データとそれを保護するルールが明らかに一緒に属している場合は、クラスに到達します。

よくある間違い

可変クラス属性の使用

これは典型的なバグです。リストはクラスで定義されているため、すべてのカートがそれを共有します。

class Cart:
    items = []            # shared by every cart!

    def add(self, item):
        self.items.append(item)

c1, c2 = Cart(), Cart()
c1.add("pen")
print(c2.items)

# ['pen']

__init__ と self.items = [] で作成すると、すべてのオブジェクトが独自のリストを取得します。

その他の一般的なエラー

  • selfを忘れます。 メソッド内に balance ではなく self.balance を記述します。
  • 忘れる super().__init__(). その後、子は親によって設定された属性を見逃します。
  • 巨大なクラスの構築。 すべてを行うクラスはテストが困難です。責任ごとに分けてください。
  • 深い継承。 通常は 2 レベルで十分で、構成がより明確になることがよくあります。
  • テストを作成しません。pytest チュートリアルで小さなカートを使用することを示しているように、ルールのあるクラスはテストが簡単です。

まとめ

オブジェクト指向 Python は、結局のところ、データを保護する動作でデータをグループ化することになります。 __init__、メソッド、__str__ から始めて、解決できる問題に遭遇したら継承とプロパティを追加します。次のステップとして、同じいくつかの変数をあらゆる場所に渡すスクリプトを作成し、それらを 1 つの小さなクラスに変換します。

よくある質問

クラスとオブジェクトの違いは何ですか?

クラスは定義、つまり設計図です。オブジェクトは、独自のデータを備えたオブジェクトから作成された特定のインスタンスです。 1 つのクラスで多数のオブジェクトを作成できます。

Python の __init__ は何をしますか?

これはイニシャライザであり、オブジェクトの作成時に自動的に実行されます。通常、渡した引数からオブジェクトの開始属性を設定します。

Python における self とは何ですか?

self は、メソッドが呼び出されるオブジェクトを指します。 Python はそれを自動的に渡し、メソッドがそのオブジェクトの属性を読み取って変更できるようにします。

OOP の 4 つの柱とは何ですか?

それらは、カプセル化、抽象化、継承、ポリモーフィズムです。これらを組み合わせることで、データと動作をバンドルし、詳細を非表示にし、コードを再利用することができます。

関数の代わりにクラスを使用する必要があるのはどのような場合ですか?

データと動作が複数の操作にわたって一緒に属する場合は、クラスを使用します。ステートレスな操作の場合、プレーン関数の方がシンプルでテストが簡単です。

学び続ける

Stack Quoraと連携する

テスト、WordPress、または SEO についてサポートが必要ですか?

私たちは、チームがより優れたソフトウェアを出荷し、サイトを成長させるのを支援します。あなたが取り組んでいることを教えてください。明確な次のステップを提案します。

読み続けてください

詳しいガイドはこちら テスト、AI、最新の開発

この記事は気に入りましたか?トピックを選択して、最新のチュートリアルに直接アクセスしてください。

人工知能

AI 幻覚の説明: 言語モデルが物事をでっち上げる理由とそれを軽減する方法

AI 幻覚について説明しました。幻覚とは何か、言語モデルが幻覚を生成する理由、一般的な種類、グラウンディングとプロンプトで幻覚を軽減する方法、そして私たちが実行した簡単なチェックです。

記事を読む →
DevOps

環境変数の説明: .env ファイル、シークレット、および設定が正しく行われている

実行した Python の例を使用して環境変数について説明します。環境変数の読み取りと設定、すべての値が文字列である理由、.env ファイル、プロセスの継承、シークレット、検証について説明します。

記事を読む →
ソフトウェア開発

API レート制限の説明: アルゴリズム、ヘッダー、および 429 エラーの処理

API レート制限については、実行したシミュレーションで説明します。トークン バケット、固定ウィンドウ、スライディング ウィンドウ、429 応答、レート制限ヘッダー、バックオフによる再試行、およびテスト制限です。

記事を読む →
テスト自動化

Python でのモッキング:unittest.mock、patch、およびテストを嘘にする間違い

Python でのunittest.mockによるモック、テスト済み: モックとreturn_value、side_effect、名前が使用されている場所のパッチ、仕様と自動仕様、日付のモック、およびよくある間違い。

記事を読む →
ソフトウェアテスト

コードカバレッジの説明: 回線カバレッジとブランチカバレッジ、および 100% の実際の意味

実際のcoverage.pyの実行でコードカバレッジを説明: 行、分岐、条件のカバレッジ、レポートの読み取り、100%のカバレッジでもバグを見逃す可能性がある理由、および賢明なターゲット。

記事を読む →
データベースとSQL

SQL における DELETE、TRUNCATE、DROP: 違い、ロールバック、およびそれぞれをいつ使用するか

DELETE、TRUNCATE、DROP について、テスト済み SQL を使用して説明します。それぞれの削除内容、ロールバック、トリガー、ID リセット、速度、PostgreSQL、MySQL、SQL Server、SQLite の違いについて説明します。

記事を読む →
データベースとSQL

SQL ビューの説明: 作成、使用、落とし穴の回避、例を示します

SQL ビューについて、実行したクエリとともに説明しました。ビューの作成、ライブ結果、列の非表示、パフォーマンス、更新可能なビューと具体化されたビュー、壊れた依存関係、ベスト プラクティスについて説明します。

記事を読む →
ソフトウェア開発

TypeScript インターフェイスと型: 実際の違い、コンパイラでテスト

TypeScript インターフェイスと型、実際のコンパイラでチェック: 両方でできること、片方だけでできること、宣言のマージ、拡張と交差、および従うべき簡単なルール。

記事を読む →
ソフトウェア開発

Python *args と **kwargs の説明: 柔軟な関数と明確な例

Python の *args と **kwargs について、実行したコードで説明しました。パッキングとアンパッキング、パラメーターの順序、キーワードのみの引数と位置のみの引数、デコレーター、一般的なエラーです。

記事を読む →
ソフトウェア開発

Python Lambda 関数: 構文、実際の用途、および使用すべきでない場合

Python のラムダ関数について、実行したコードとともに説明します。構文、キーによるソート、マップとフィルター、クロージャー、遅延バインディング トラップ、通常の def がより適切な選択である場合。

記事を読む →
人工知能

AIエージェントとは何ですか?シンプルなエージェント ループを実行できる仕組み

AIエージェントとは何ですか?エージェント ループ、ツール、メモリ、ガードレール、実行した小さな Python ループ、実際のリスク、およびシンプルなチャットボットがより良い選択である場合についてのわかりやすいガイドです。

記事を読む →
DevOps

モニタリングと可観測性: ログ、メトリクス、トレースによる本当の違い

モニタリングと可観測性について説明: 既知および未知の障害、ログ、メトリクスとトレース、チェックアウト インシデントのウォークスルー、ゴールデン シグナル、OpenTelemetry、および便利なアラート。

記事を読む →
DevOps

Docker ボリュームとバインド マウント: コンテナ データを正しい方法で保持する

Docker ボリュームとバインド マウントについて説明します。コンテナ データが消える理由、名前付きボリューム、バインド マウント、tmpfs、Compose の例、バックアップ、アクセス許可、およびそれぞれをいつ使用するかについて説明します。

記事を読む →
テスト自動化

TDD と BDD: 主な違い、1 つの機能が両方の方法で構築され、それぞれをいつ使用するか

TDD と BDD は、両方の方法で構築された 1 つの割引機能で説明されています。実行したコードによるレッド-グリーン-リファクタリング、Given-When-Then シナリオ、ツール、トレードオフ、およびそれぞれをいつ使用するかです。

記事を読む →
ソフトウェアテスト

ユーザー受け入れテスト (UAT): プロセス、チェックリスト、および実際の例

ユーザー受け入れテストの説明: 誰が実行するか、QA との違い、7 段階のプロセス、UAT テスト ケース テンプレート、チェックリスト、サインオフ基準、およびよくある間違い。

記事を読む →
データベースとSQL

SQL NULL 値の説明: IS NULL、COALESCE、NULLIF、および回避すべきトラップ

SQL の NULL 値について、実行したクエリで説明しました。3 つの値のロジック、IS NULL、COALESCE、NULLIF、集計、結合、並べ替えでの NULL の扱い方、およびそれが密かに引き起こすバグです。

記事を読む →
データベースとSQL

SQL CASE WHEN ステートメント: 構文、実際の例、およびよくある間違い

SQL CASE WHEN では、単純な検索フォーム、条件順序、SUM を使用したピボット、COUNT トリック、カスタム並べ替え、更新、回避すべき NULL トラップなど、実行したクエリを使用して説明しました。

記事を読む →
ソフトウェア開発

JWTとは何ですか? JSON Web トークンを実際の例で説明する

JWTとは何ですか? JSON Web トークンについて説明しました。3 つの部分、実行したコード内で構築および改ざんされたトークン、JWT とセッション、ストレージ、リフレッシュ トークン、およびセキュリティ上の間違いです。

記事を読む →
ソフトウェア開発

JavaScript イベントループの説明: コールスタック、マイクロタスク、タイマーと例

JavaScript イベント ループについて、実行したコードで説明しました。コール スタック、タスク キュー、マイクロタスク キュー、setTimeout 0 が即時ではない理由、ブロッキング、スターベーション、およびインタビュー クイズです。

記事を読む →
ソフトウェア開発

Python ジェネレーターと収量の説明: 実際の例でメモリを節約する

Python ジェネレーターと Yield について、実行したコードを使用して説明します。一時停止と再開の方法、メモリ節約の測定、パイプライン、無限シーケンス、Yield from、send、および一般的なトラップについて説明します。

記事を読む →
人工知能

埋め込みとは何ですか?ベクトルとコサインの類似度を簡単に説明

埋め込みとは何ですか?ベクトル、コサイン類似度、セマンティック検索に関する平易なガイド。私たちが実行した小さな例、一般的な使用法、モデルの選択、既知の制限が含まれています。

記事を読む →
DevOps

Blue-Green デプロイメントと Canary デプロイメント: 違い、トレードオフ、および選択方法

ブルー グリーン デプロイメントとカナリア デプロイメントについて説明: それぞれの仕組み、コスト、リスクとロールバック、テストした安定したユーザー バケット化、データベース移行、ローリング アップデート、および選択方法。

記事を読む →
テスト自動化

不安定なテスト: 問題の原因とそれを永久に修正する方法

不安定なテストについては、私たちが実行したデモを使用して説明しました。主な原因、確認および診断する方法、タイミングの適切な修正、共有された状態と日付、隔離プロセスなどです。

記事を読む →
ソフトウェアテスト

負荷テストとストレス テスト: 違い、メトリクス、および k6 の例

ロード テストとストレス テストについて説明します。それぞれが何を証明するか、スパイク テストとソーク テスト、重要な指標、平均値が誤解を招く理由、K6 の例、テストの計画方法について説明します。

記事を読む →
ソフトウェアテスト

テスト ケースとテスト シナリオ: 主な違い、例、およびそれぞれをいつ使用するか

テスト ケースとテスト シナリオの説明: 明確な定義、並べて表、シナリオからケースへの 1 つのパスワード リセット機能、テンプレート、およびそれぞれをいつ使用するか。

記事を読む →
データベースとSQL

SQL クエリの最適化: 実行プランを読み取り、タイミングを考慮して遅いクエリを修正

SQL クエリの最適化は 100 万行でテストされています。実行プランの読み取り、適切なインデックスの追加、検索対象外のフィルターの修正、複合インデックスとキーセットのページネーションの使用。

記事を読む →
データベースとSQL

SQL UNION と UNION ALL: 違い、例、テストされたパフォーマンス

SQL UNION と UNION ALL について、実行したクエリで説明しました。重複、両方に従うルール、実際のデータのバグ、測定されたパフォーマンス、INTERSECT と EXCEPT、およびそれぞれをいつ使用するかについて説明します。

記事を読む →
ソフトウェア開発

JavaScript Fetch API チュートリアル: GET、POST、エラー処理、タイムアウト

ローカル サーバーに対してテストされた JavaScript Fetch API チュートリアル: GET と POST、404 がスローされない理由、再利用可能なヘルパー、クエリ文字列、タイムアウト、CORS、およびよくある間違い。

記事を読む →
ソフトウェア開発

Python ファイル処理: 読み取り、書き込み、CSV、JSON、パスライブラリと例

Python のファイル処理について、実行したコードで説明します。オープン モード、大きいファイルの読み取り、CSV、JSON、パスライブラリ、バイナリ ファイル、安全な書き込み、エラー処理、およびよくある間違いについて説明します。

記事を読む →
ソフトウェア開発

Python のクラスとオブジェクト: 実際の例を含む OOP チュートリアル

Python のクラスとオブジェクトについて、実行したコードとともに説明します: __init__、メソッド、クラスとインスタンスの属性、継承、プロパティ、ダンダー メソッド、データクラス、およびよくある間違い。

記事を読む →
人工知能

大規模言語モデルとは何ですか? LLM の仕組みを誇大広告なしで説明

大規模言語モデルとは何ですか? LLM は、トークン、エンベディング、アテンション、トレーニング、温度およびコンテキスト ウィンドウ、小さな次の単語のデモ、実際の制限など、平易な言葉で説明されています。

記事を読む →
DevOps

初心者のための Linux コマンド: 例を含む基本ターミナル ガイド

初心者向けの Linux コマンド。ナビゲーション、ファイル、ログの表示、grep、パイプ、権限、プロセス、アーカイブなどのタスク別にグループ化されており、実用的なログ分析の例も含まれています。

記事を読む →
テスト自動化

Selenium と Playwright: 主な違い、コードの比較、どちらを選択するか

Selenium と Playwright の比較: アーキテクチャ、待機、ブラウザと言語のサポート、デバッグ、両方のツールでの同じテスト、移行のアドバイスと選択方法。

記事を読む →
ソフトウェアテスト

等価性分割: テスト設計手法を実際の例で説明

等価性パーティション化について説明しました。有効なパーティションと無効なパーティションを見つける方法、年齢、パスワード、クーポンに関する実際の例、実行したテスト、境界と組み合わせる理由。

記事を読む →
ソフトウェアテスト

ソフトウェアテストにおける重大度と優先度: 相違点、マトリックス、および実際の例

ソフトウェア テストにおける重大度と優先度について説明します。明確な定義、例を含む 4 方向のマトリックス、レベル スケール、それぞれの設定者、バグ トリアージの実行方法。

記事を読む →
データベースとSQL

SQL サブクエリのチュートリアル: 型、相関サブクエリ、および EXISTS と例

実行したクエリを含む SQL サブクエリのチュートリアル: スカラー、IN、FROM、SELECT サブクエリ、相関サブクエリ、EXISTS、NOT IN NULL トラップ、サブクエリ対 JOIN 対 CTE。

記事を読む →
データベースとSQL

SQL トランザクションと ACID の説明: COMMIT、ROLLBACK、分離レベル

SQL トランザクションと ACID について、実行した銀行振込で説明しました。COMMIT、ROLLBACK、セーブポイント、ロック、分離レベル、ダーティ リード、デッドロック、ベスト プラクティスについて説明します。

記事を読む →
ソフトウェア開発

Git mergeとrebaseの違い:例と使い分け

Git mergeとrebaseの違いを、実際のログ出力、比較表、rebaseの黄金律、安全なチームワークフローで解説します。

記事を読む →
ソフトウェア開発

Pythonのリスト内包表記:構文・例・使うべきでない場面

Pythonのリスト内包表記を解説:構文、フィルタ、if-else、ネストしたループ、実測した処理時間、そして通常のforループの方が良い場面。

記事を読む →
データベースとSQL

SQL JOINを例で解説(Inner・Left・Right・Full)

サンプルのテーブルとクエリでSQL JOINを順に解説。INNER、LEFT、RIGHT、FULL、CROSS、SELFに加え、よくある間違いとパフォーマンスのコツも紹介します。

記事を読む →