| この記事の要点 |
|
__init__ が初期化を担当する
class User:
def __init__(self, name, age=0):
self.name = name
self.age = age
print("初期化されました")
u = User("田中", 30) # 初期化されました
print(u.name, u.age) # 田中 30
User("田中", 30) と書いたとき、Python は内部で次の順に処理しています。
| 順 | 呼ばれるもの | 役割 | 戻り値 |
|---|---|---|---|
| 1 | __new__(cls, ...) | インスタンスを作る | 作ったインスタンス |
| 2 | __init__(self, ...) | 作られたものを初期化する | None でなければならない |
__init__ で return に値を書くと TypeError: __init__() should return None になります。「戻り値を返すコンストラクタ」を作りたい場合は次の @classmethod を使います。
オーバーロードはできない
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
def __init__(self, text): # ← 上書きされる。エラーにもならない
self.x, self.y = map(int, text.split(","))
Point(1, 2) # TypeError: __init__() takes 2 positional arguments but 3 were given
Python の関数定義は名前への代入なので、同名で 2 回書くと後の定義だけが残ります。引数の数や型で切り替える仕組みはありません。
方法 1: デフォルト引数でまとめる
class Point:
def __init__(self, x=0, y=0):
self.x, self.y = x, y
Point() # (0, 0)
Point(1) # (1, 0)
Point(1, 2) # (1, 2)
Point(y=5) # (0, 5) キーワード指定もできる
方法 2: classmethod のファクトリ(推奨)
class Point:
def __init__(self, x, y):
self.x, self.y = x, y
@classmethod
def from_text(cls, text): # "1,2" から作る
x, y = map(int, text.split(","))
return cls(x, y)
@classmethod
def origin(cls): # 原点を作る
return cls(0, 0)
p1 = Point(1, 2)
p2 = Point.from_text("3,4")
p3 = Point.origin()
作り方ごとに名前が付くため、どの生成方法なのかが呼び出し側で一目で分かります。cls(...) と書いておけば、継承したクラスから呼んでも正しく子クラスのインスタンスが返ります。
継承したら super().__init__() を呼ぶ
class User:
def __init__(self, name):
self.name = name
class Admin(User):
def __init__(self, name, level):
super().__init__(name) # ← これが無いと self.name が作られない
self.level = level
a = Admin("田中", 3)
print(a.name, a.level) # 田中 3
class Broken(User):
def __init__(self, name, level):
self.level = level # super() を呼び忘れた
b = Broken("田中", 3)
print(b.name) # AttributeError: 'Broken' object has no attribute 'name'
子クラスで __init__ を定義しなければ、親の __init__ がそのまま使われます。定義した瞬間に親の初期化は行われなくなるので、super().__init__() の呼び忘れが最頻出のバグです。
__new__ を使う場面
__new__ を書く必要があるのは、イミュータブルな型を継承したときと生成そのものを制御したいときだけです。
class UpperStr(str): # str は生成後に中身を変えられない
def __new__(cls, value):
return super().__new__(cls, value.upper())
print(UpperStr("abc")) # ABC
# シングルトン(常に同じ 1 個を返す)
class Config:
_instance = None
def __new__(cls):
if cls._instance is None:
cls._instance = super().__new__(cls)
return cls._instance
print(Config() is Config()) # True
__new__ がそのクラスのインスタンス以外を返すと __init__ は呼ばれません。シングルトンでは __init__ が生成のたびに走る点にも注意が必要です(初期化済みフラグを持たせるか、__init__ を空にします)。
データの入れ物なら dataclass
from dataclasses import dataclass, field
@dataclass
class User:
name: str
age: int = 0
tags: list[str] = field(default_factory=list) # 可変な既定値はこう書く
def __post_init__(self): # __init__ の直後に呼ばれる
if self.age < 0:
raise ValueError("age は 0 以上にしてください")
u = User("田中", 30)
print(u) # User(name='田中', age=30, tags=[])
__init__ / __repr__ / __eq__ が自動生成されます。属性を並べるだけの __init__ を書いているなら @dataclass にできます。
なお tags: list[str] = [] と書くと ValueError: mutable default で弾かれます。dataclass は 変数 で説明した「デフォルト引数の共有」問題を防ぐため、default_factory を強制します。
デストラクタ(__del__)は当てにしない
class Handle:
def __del__(self):
print("破棄") # いつ呼ばれるか保証がない
# 後始末は with 文で明示する
class Handle:
def __enter__(self):
print("開く")
return self
def __exit__(self, exc_type, exc, tb):
print("閉じる") # 例外が起きても必ず呼ばれる
with Handle():
print("処理中")
ファイルや接続の解放は __del__ ではなく with 文(コンテキストマネージャ)で行います。
関連
子ページはありません
人気ページ
- 1 Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法
- 2 tomcat の起動 / 停止ログと catalina.log・catalina.out の違い
- 3 JavaScript で base URL を取得する方法|window.location.origin
- 4 YouTube Data API v3 エラー一覧|403・400・404 の原因と対処
- 5 Laravel エラー一覧|500/Blade/DB 接続/ルーティングの代表エラー
- 6 3Dグラフィックスのソフト一覧|Blender・Metasequoiaと用途別の選び方
- 7 Spring Frameworkのアノテーション一覧
- 8 【Spring】@Valueアノテーションとは
- 9 CATALINA_HOME の確認方法 (Linux / Mac)
- 10 【Spring】@Autowiredアノテーションとは
最近更新/作成されたページ
- Visual Studio「デザイナーを表示できません」エラーの原因と対処 2026-10-28 12:06:00
- SSH 認証に失敗しました。再試行してください の対処 2026-10-28 12:06:00
- SSH2 秘密鍵の読み込みに失敗しました の原因と対処 2026-10-28 12:06:00
- TeraTerm のよくあるエラーと対処法完全ガイド — Connection refused / 2026-10-28 12:06:00
- Visual Studio エラー一覧|コンパイルエラー・警告の確認方法と対処 2026-10-28 11:39:57
- Whitelabel Error Page の原因と消し方|Spring Boot のエラーページ 2026-10-28 11:39:57
- Eclipseで「サーバーに追加または除去できるリソースがありません。」の原因と対処法 2026-10-28 11:39:57
- SQL WHERE 句完全ガイド 2026-10-28 11:39:57
- SQL JOIN 完全ガイド (INNER/LEFT/RIGHT/FULL OUTER) 2026-10-28 11:39:57
- tomcat の起動 / 停止ログと catalina.log・catalina.out の違い 2026-10-28 10:24:23
- Tomcat の起動確認方法 5 つ|localhost:8080・ポート・プロセス・ログ 2026-10-28 10:24:23
- Oracle 19c COMMITの使い方: 暗黙コミット・自動確定・応答不明時の確認 2026-10-28 09:59:09
- Oracle 19c DELETE文|削除対象の確認・COMMIT前の判断・ROLLBACKの条件 2026-10-28 09:59:09
- Oracle 19c INSERT文|INSERT ALL・SELECT・RETURNINGとMERGEの使い分け 2026-10-28 09:59:09
- Oracle 19cのトランザクション制御|COMMIT・ROLLBACK・分離レベルと接続設定 2026-10-28 09:59:09