`__slots__`の使用方法と利点
Pythonの`__slots__`は、クラスのインスタンス属性を固定することでメモリ効率を改善し、属性の動的な追加を防ぐ機能です。通常、Pythonのクラスインスタンスは辞書(`__dict__`)を持ち、動的に属性を追加できますが、これはメモリ使用量が多いです。`__slots__`を使用すると、`__dict__`が生成されず、代わりに各インスタンス属性に対して固定されたスペースのみが用意されます。これにより、メモリ使用量が削減され、属性へのアクセス速度が向上します。
実装方法
`__slots__`を使用するには、クラス定義内に`__slots__`属性を設定し、許可される属性名をタプルで指定します。以下にその実装例を示します。
class Point:
__slots__ = ('x', 'y')
def __init__(self, x, y):
self.x = x
self.y = y
この例では、`Point`クラスは`x`と`y`のみを属性として持ち、これらは事前に`__slots__`で定義されています。このため、このクラスのインスタンスは他の属性を持つことができません。
サンプルコード1: __slots__の基本的な使用
class Rectangle:
__slots__ = ('width', 'height')
def __init__(self, width, height):
self.width = width
self.height = height
def area(self):
return self.width * self.height
rect = Rectangle(5, 10)
print("Area:", rect.area()) # 出力: Area: 50
サンプルコード2: __slots__を使ったエラーの例
class Circle:
__slots__ = ('radius',)
def __init__(self, radius):
self.radius = radius
circle = Circle(5)
try:
circle.color = 'red' # これはエラーを引き起こします
except AttributeError as e:
print("Error:", e) # 出力: Error: 'Circle' object has no attribute 'color'
サンプルコード3: 継承と__slots__
class Shape:
__slots__ = ('id',)
class Circle(Shape):
__slots__ = ('radius',)
def __init__(self, id, radius):
self.id = id
self.radius = radius
circle = Circle(101, 5)
print("Circle ID:", circle.id, "Radius:", circle.radius) # 出力: Circle ID: 101 Radius: 5
上記のサンプルコード3では、`Shape`クラスとそのサブクラス`Circle`が`__slots__`を使用しています。継承を使用する場合、サブクラスはスーパークラスの`__slots__`に加えて独自の`__slots__`を定義することができます。
これらの例からわかるように、`__slots__`を使用すると、メモリ効率の良いクラス設計が可能になりますが、柔軟性が制限される点に注意が必要です。特に、大規模なプログラムやライブラリで`__slots__`を使用する場合は、その影響を慎重に評価することが推奨されます。
