この記事では、クラスで使用するデータメンバーを「__slots__」を使って明示的に指定する方法を解説します。
クラスで使用するデータメンバーを明示的に指定することで、そのクラスを「軽量化」 + 「高速化」することができます。
それでは、指定する方法を見ていきましょう!
クラスに__slots__
という名前のクラス変数を定義します。__slots__
には、そのクラスで使用するデータメンバーの名前を文字列で指定できます。
class Person:
__slots__ = 'name'
def __init__(self, name: str) -> None:
self.name = name
使用するデータメンバーが複数存在する場合は、タプルやリストなどにまとめて指定します。
class Person:
__slots__ = 'name', 'age'
def __init__(self, name: str, age: int) -> None:
self.name = name
self.age = age
__slots__
を使用することで以下のような効果があります。
__slots__
を定義することで__dict__
や__weakref__
を自動生成しなくなります。それによりクラスを軽量化することができます。
試しに通常のクラスとデータメンバーを指定したクラスのサイズを比較してみます。
通常
class Person:
def __init__(self, name: str, age: int) -> None:
self.name = name
self.age = age
print(sys.getsizeof(Person))
実行結果
1072
データクラスを指定
class Person:
__slots__ = 'name', 'age'
def __init__(self, name: str, age: int) -> None:
self.name = name
self.age = age
print(sys.getsizeof(Person))
実行結果
904
__slots__
を定義するだけで100バイト以上軽量化することができました。また、属性の検索速度も大幅に改善されるようです。
ただし、__dict__や弱参照をサポートしていない点には注意してください。
__slots__
を定義したクラスでは、動的に属性を追加することができなくなります。
一見デメリットのように感じるかもしれませんが、属性を後から追加する予定がないクラスの場合ではむしろ安全性が増します。
class Person:
__slots__ = 'name', 'age'
def __init__(self, name: str, age: int) -> None:
self.name = name
self.age = age
mike = Person('Mike', 20)
# __slots__にない属性を追加
mike.gender = 'man'
実行結果
Traceback (most recent call last):
File "main.py", line 13, in
mike.gender = 'man'
AttributeError: 'Person' object has no attribute 'gender'
これにより変数名間違いなどの心配もなくなります。
この記事では、クラスのデータメンバーを明示的に指定する方法を解説しました。
__slots__
を使うことでクラスを「軽量化」+「高速化」することができます。__dict__
や弱参照を使わないかつ、動的に変数を追加しない場合は積極的に使っていきましょう!
それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ