Code
class Dog:
def __init__(self, name):
self.name = name
my_dog = Dog("Pochi") # ← これがインスタンスRyo Nakagami
2025-11-03
2025-11-07
Definition 1 プログラミングにおけるオブジェクト
上記の意味でのオブジェクトを作るための設計図がPythonにおける「クラス」です.クラスを基にしてオブジェクトが生成されますが, 実際にデータ値が格納されたオブジェクトのことをインスタンスといいます.
コード行 my_dog = Dog("Pochi") の挙動は以下のように分解できます
Dog クラスの定義を探し出すself,引数 Pochi を name として渡して,オブジェクトの __init__ を呼び出すname の値をインスタンスに格納する.my_dog という名前を与える(変数 my_dog に格納する)Example 1 (メモリから見たクラスとインスタンスの違い)
Dog は クラスオブジェクト(型そのもの)を指しており,<class '__main__.Dog'> のように表示されるmy_dog は Dogクラスから生成されたインスタンス(具体的な値を持つ実体)を指しており,メモリアドレスを伴って表示されるDefinition 2 クラス属性とインスタンス属性
__init__() メソッド内で self.xxx = ... の形で定義される.Example 2 (dataclass とクラス変数)
dataclass でクラス変数を作る場合は ClassVar を使うdataclassはインスタンス変数を自動的に __init__ 処理するための仕組みなので,ClassVar を付けないとクラス変数を用いるとき「インスタンス変数っぽく見える」という混乱が起こりますself.__class__ を基本用いるfrom dataclasses import dataclass
from typing import ClassVar
@dataclass
class Person:
name: str # インスタンス属性
age: int # インスタンス属性
total_number_of_persons: ClassVar[int] = 0
def __post_init__(self):
# クラス属性
self.__class__.total_number_of_persons += 1
adam = Person('Adam', 30)
john = Person('Jhon', 25)
print(Person.total_number_of_persons)
print(adam.total_number_of_persons)
print(john.total_number_of_persons)2
2
2
Coding Style Guide
tuple や frozenset を使うExample 3
from dataclasses import dataclass, field
from typing import Tuple, ClassVar
@dataclass
class Stats:
# 不変のクラス変数(mutable global state を避ける)
_ATTRIBS: ClassVar[Tuple[str, ...]] = ('strength', 'speed', 'intellect', 'tenacity')
# インスタンス属性
strength: int = 0
speed: int = 0
intellect: int = 0
tenacity: int = 0
# クラスメソッドで安全にアクセス
@classmethod
def attribs(cls) -> Tuple[str, ...]:
"""Return the immutable tuple of attribute names."""
return cls._ATTRIBS
# combine メソッドは staticmethod
@staticmethod
def combine(*args: 'Stats') -> 'Stats':
"""
Combine multiple Stats objects into a new Stats instance.
Uses the class-level attribute names safely.
"""
assert all(isinstance(arg, Stats) for arg in args), "All arguments must be Stats instances."
combined_values = {stat: 0 for stat in Stats.attribs()}
for stat in Stats.attribs():
for obj in args:
combined_values[stat] += getattr(obj, stat)
return Stats(**combined_values)
s1 = Stats(strength=10, speed=5)
s2 = Stats(intellect=7, tenacity=3)
s_total = Stats.combine(s1, s2)
print(s_total)
# クラス変数は不変なので安全
print(Stats.attribs()) # ('strength', 'speed', 'intellect', 'tenacity')Stats(strength=10, speed=5, intellect=7, tenacity=3)
('strength', 'speed', 'intellect', 'tenacity')
__ をメソッドや属性名の先頭に付与することで,クラス定義の外からは見えづらくする命名方法があります.
Tama says Meow!
このように__name 属性は内部経由だと利用できますが,my_cat.__name だとエラーができます.ただし,
Tama
Tama2
とすると一応アクセス(READ及びWRITE)が出来てしまいます.
ゲッターとセッターを用いて,インスタンス属性へのアクセスを制御したい場合は @property, @<property>.setter デコレーターという仕組みを使います.
Example 4 (トラファルガー・ローとマングリングとゲッターとセッター)
ワンピースのトラファルガー・ローを例にすると
ということを踏まえてClassを定義すると
class Waterloos:
def __init__(self, real_name):
self.__real_name = real_name
parts = self.__real_name.split("・")
self._nickname = f"{parts[0]}・{parts[-1]}" if len(parts) > 1 else self.__real_name
@property
def name(self):
"""通称(ニックネーム)を返す"""
return self._nickname
@name.setter
def name(self, value):
"""通称を更新"""
if not isinstance(value, str):
raise ValueError("Nickname must be a string")
self._nickname = value
# トラファルガー・ローの設定
p = Waterloos(real_name="トラファルガー・D・ワーテル・ロー")
print("通称:", p.name) # → トラファルガー・ロー
print("本名:", p._Waterloos__real_name) # → トラファルガー・D・ワーテル・ロー
# print("本名:", p.__real_name) # これではアクセスできない通称: トラファルガー・ロー
本名: トラファルガー・D・ワーテル・ロー
ワノ国に入国した後に,ワノ国風名前にアレンジしたとすると