`__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__`を使用する場合は、その影響を慎重に評価することが推奨されます。