次の非常に単純なデータクラスがあります。
import dataclasses
@dataclasses.dataclass
class Test:
value: int
クラスのインスタンスを作成しますが、整数の代わりに文字列を使用します。
>>> test = Test('1')
>>> type(test.value)
<class 'str'>
私が実際に欲しいのは、クラス定義で定義されたデータ型iへの強制変換です。
>>> test = Test('1')
>>> type(test.value)
<class 'int'>
__init__
メソッドを手動で記述する必要がありますか、またはこれを達成する簡単な方法はありますか?
データクラス属性のタイプヒントは、タイプが強制またはチェックされるという意味では決して守られません。 mypy のようなほとんどの静的型チェッカーはこの仕事をすることが期待されており、Pythonは実行されないので、実行時にそれを行いません。
手動の型チェックコードを追加する場合は、 ___post_init__
_ メソッドで追加します。
_@dataclasses.dataclass
class Test:
value: int
def __post_init__(self):
if not isinstance(self.value, int):
raise ValueError('value not an int')
# or self.value = int(self.value)
_
dataclasses.fields(self)
を使用して、フィールドとタイプを指定する Field
オブジェクトのタプルを取得し、これをループすることができますフィールドごとに個別に書き込むことなく、フィールドごとに自動的に。
_def __post_init__(self):
for field in dataclasses.fields(self):
value = getattr(self, field.name)
if not isinstance(value, field.type):
raise ValueError(f'Expected {field.name} to be {field.type}, '
f'got {repr(value)}')
# or setattr(self, field.name, field.type(value))
_
これは、__post_init__
メソッドを使用して実現できます。
import dataclasses
@dataclasses.dataclass
class Test:
value : int
def __post_init__(self):
self.value = int(self.value)
このメソッドは__init__
メソッドの後に呼び出されます
https://docs.python.org/3/library/dataclasses.html#post-init-processing
ええ、簡単な答えは、自分自身の__init__()
で変換を自分で行うことです。これは、オブジェクトが必要なためですfrozen=True
。
型検証については、Pydandicはそれを行うと主張していますが、まだ試していません: https://pydantic-docs.helpmanual.io/