I'd like to initialize A from a dict which can contain unexpected keys. I'd like to initialize with the given, known keys and ignore the rest
` from dataclasses import dataclass
@dataclass class A: a: str b: int
a1 = A({'a': 'Foo', 'b': 123}) # works a2 = A({'a': 'Foo', 'b': 123, 'c': 'unexpected'}) # raises TypeError `
Is there a Python feature that I'm missing or do I have to filter the dict upfront?
CodePudding user response:
Another option is to use the dataclasses.fields
function with a classmethod.
from dataclasses import dataclass, fields
@dataclass
class A:
a: str
b: int
@classmethod
def from_dict(cls, d: dict) -> "A":
field_names = (field.name for field in fields(cls))
return cls(**{k: v for k, v in d.items() if k in field_names})
a1 = A.from_dict({'a': 'Foo', 'b': 123})
a2 = A.from_dict({'a': 'Foo', 'b': 123, 'c': 'unexpected, but who cares?'})
CodePudding user response:
Apparently it is easier than I expected...
from dataclasses import dataclass
@dataclass(init=False)
class A:
a: str
b: int
def __init__(self, a: str, b: int, **therest):
self.a = a
self.b = b
The init=False
parameter of the dataclass decorator indicates you will provide a custom __init__
function. Docs here
CodePudding user response:
just replace built-in dataclass
with pydantic
implementation
from pydantic.dataclasses import dataclass
@dataclass
class A:
a: str
b: int
a1 = A(**{'a': 'Foo', 'b': 123}) # works
a2 = A(**{'a': 'Foo', 'b': 123, 'c': 'unexpected'})
print(a1, a2) # prints A(a='Foo', b=123) A(a='Foo', b=123)