Categories: Python

【Python】クラスのデータメンバーを明示的に指定する方法【__slots__】

この記事では、クラスで使用するデータメンバーを「__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__や弱参照を使わないかつ、動的に変数を追加しない場合は積極的に使っていきましょう!

それでは今回の内容はここまでです。ではまたどこかで〜( ・∀・)ノ

ゆうまる

独学でプログラミングを勉強しているおじさん。いろんな言語を勉強したが浅く広くなためあまり仕事につながらない。また忘れっぽいため自分のブログを備忘録としても使っている。産まれてこのかたずっとネコを飼ってる生粋のネコ派。最近お腹が出てきて筋トレに奮闘中!

Recent Posts

【Dart】コンストラクタのデフォルト引数について

Dartのコンストラクタのデフォルト引数…

2週間 ago

【Unity】有料アセットを無料で手に入れる方法

この記事では、Unityの有料アセットを…

4か月 ago

【Python】任意の秒数だけ処理を一時停止する方法【sleep()関数】

この記事では、Pythonで任意の秒数だ…

1年 ago

【Python】Wordの文書の新規作成と読み書き

この記事では、Pythonを使ってWor…

1年 ago

【Python】メタクラスって結局なんなの?

この記事では、Pythonのメタクラスに…

1年 ago