pythonのdataclassでkey, value, lenを使う

データの格納だけをしたい時、辞書を作成するよりもdataclassでデコレートする方が宣言が楽で便利。

__init__()を書いてインスタンス変数に代入、という作業をしなくて済むので見た目もスッキリする。

import dataclasses

@dataclasses.dataclass
class Data:
    aa: int = 11
    bb: float = 22

data = Data()

# Data(aa=11, bb=22)

しかし、辞書と違ってkeyやvalueでアクセス出来ないし、len()で個数を調べることも出来なくなってしまう。

data.keys()

# AttributeError: 'Data' object has no attribute 'keys'

len(data)

# TypeError: object of type 'Data' has no len()

__annotations__属性を経由することで、dataclassを辞書として扱うことが出来る。

data.__annotations__

# {'aa': int, 'bb': float}

data.__annotations__.keys()

# dict_keys(['aa', 'bb'])

data.__annotations__.values()

# dict_values([<class 'int'>, <class 'float'>])

len(data.__annotations__)

# 2

dataclassの値を書き換えたい時、data.aa = 111 というように更新できるが、forループなどでdataclassの値を全部更新したい時はsetattr()とgetattr()を組み合わせる。

for k in data.__annotations__.keys():
    if getattr(data, k) < 20:
        setattr(data, k, 11111)

data

# Data(aa=11111, bb=22)

参考

PEP 649 – Deferred Evaluation Of Annotations Using Descriptors | peps.python.org
Python Enhancement Proposals (PEPs)

コメント

タイトルとURLをコピーしました