Pythonにおけるクラス構成要素とアクセス修飾子
一. クラスの構成要素の分類
クラスは以下の構成要素に大別されます:
class SampleClass:
organization = 'TechAcademy' # クラス変数(共有フィールド)
__private_key = 'secret123' # プライベートクラス変数
def __init__(self, name, level): # コンストラクタ
self.name = name # インスタンス変数
self.__level = level # プライベートインスタンス変数
def display(self): # インスタンスメソッド
pass
def __internal(self): # プライベートメソッド
print('内部処理')
@classmethod # クラスメソッド
def class_method(cls):
print('クラスレベル操作')
@staticmethod # ステートレスメソッド
def utility():
print('汎用ユーティリティ')
@property # プロパティアクセサ
def status(self):
return self.__level
二. クラスメンバーの可視性
2.1 クラスレベルの公開変数
class Base:
public_data = "共有情報"
def show(self):
print(Base.public_data)
class Derived(Base):
def access(self):
print(Base.public_data)
Base.public_data # クラス経由アクセス可能
obj = Base()
obj.show() # インスタンスメソッド内からアクセス可能
child = Derived()
child.access() # 派生クラスからアクセス可能
2.2 クラスレベルのプライベート変数
class Base:
__private_data = "機密情報"
def reveal(self):
print(Base.__private_data)
class Derived(Base):
def try_access(self):
print(Base.__private_data)
Base.__private_data # 外部アクセス不可
obj = Base()
obj.__private_data # インスタンス経由アクセス不可
obj.reveal() # クラス内部メソッドからアクセス可能
child = Derived()
child.try_access() # 派生クラスからのアクセス不可
2.3 インスタンス変数の公開アクセス
class User:
def __init__(self):
self.username = "public_user"
def get_name(self):
print(self.username)
class Admin(User):
def display(self):
print(self.username)
user = User()
user.username # インスタンス直接アクセス
user.get_name() # メソッド経由アクセス
admin = Admin()
admin.display() # 派生クラスからのアクセス
2.4 インスタンス変数のプライベート制限
class User:
def __init__(self):
self.__username = "private_user"
def get_name(self):
print(self.__username)
class Admin(User):
def display(self):
print(self.__username)
user = User()
user.__username # 外部アクセス不可
user.get_name() # クラス内部メソッドからアクセス可能
admin = Admin()
admin.display() # 派生クラスからのアクセス不可
2.5 公開メソッドのアクセス
class Engine:
def start(self):
print('Engine started')
class Car(Engine):
def drive(self):
print('Driving...')
def use_engine(self):
self.start()
car = Car()
car.drive() # 直接メソッド呼び出し
car.use_engine() # クラス内部からメソッド呼び出し
car.start() # 派生クラスから親メソッド呼び出し
2.6 プライベートメソッドの制限
class Engine:
def __start(self):
print('Engine started internally')
class Car(Engine):
def __drive(self):
print('Private driving method')
def use_engine(self):
self.__drive()
car = Car()
car.__drive() # 外部アクセス不可
car.use_engine() # クラス内部からアクセス可能
car.__start() # 派生クラスからのアクセス不可
三. 特殊なメソッド種別
3.1 クラスメソッドの活用例
class StudentRegistry:
__total = 0
def __init__(self, name):
self.name = name
StudentRegistry.register()
@classmethod
def register(cls):
cls.__total += 1
@classmethod
def count_students(cls):
return cls.__total
s1 = StudentRegistry("山田")
s2 = StudentRegistry("佐藤")
print(StudentRegistry.count_students())
3.2 ステートレスメソッドの実装
class TimeUtility:
@staticmethod
def current_time():
from datetime import datetime
return datetime.now().strftime("%H:%M:%S")
print(TimeUtility.current_time())
clock = TimeUtility()
print(clock.current_time())
3.3 プロパティの動的計算
class HealthIndex:
def __init__(self, weight, height):
self.weight = weight
self.height = height
@property
def bmi(self):
return self.weight / (self.height ** 2)
person = HealthIndex(70, 1.75)
print(f"BMI: {person.bmi}")
商品価格管理の例:
class Product:
def __init__(self):
self._base_price = 5000
self._discount_rate = 0.9
@property
def final_price(self):
return self._base_price * self._discount_rate
@final_price.setter
def final_price(self, new_base):
self._base_price = new_base
item = Product()
print(item.final_price)
item.final_price = 6000
print(item.final_price)
四. インスタンス判定と継承関係
4.1 isinstanceの使用例:
class Animal:
pass
class Dog(Animal):
pass
pet = Dog()
print(isinstance(pet, Dog))
print(isinstance(pet, Animal))
4.2 継承関係の確認:
class Vehicle:
pass
class Car(Vehicle):
pass
class Convertible(Car):
pass
print(issubclass(Car, Vehicle))
print(issubclass(Convertible, Vehicle))
型間の関係確認:
from collections.abc import Sequence
print(isinstance([1,2,3], list))
print(isinstance([1,2,3], Sequence))
print(issubclass(list, Sequence))