问题
I have the following dataclass:
@dataclass
class Image:
content_type: str
data: bytes = b''
id: str = ""
upload_date: datetime = None
size: int = 0
def to_dict(self) -> Dict[str, Any]:
result = {}
if self.id:
result['id'] = self.id
if self.content_type:
result['content_type'] = self.content_type
if self.size:
result['size'] = self.size
if self.upload_date:
result['upload_date'] = self.upload_date.isoformat()
return result
Is there any way to simplify to_dict
method? I don't want to list all of the fields using if
.
回答1:
As suggested by meowgoesthedog, you can use asdict and filter the result to skip falsy values:
from dataclasses import dataclass, asdict
from datetime import datetime
from typing import Dict, Any
@dataclass
class Image:
content_type: str
data: bytes = b''
id: str = ""
upload_date: datetime = None
size: int = 0
def to_dict(self) -> Dict[str, Any]:
return {k: v for k, v in asdict(self).items() if v}
print(Image('a', b'b', 'c', None, 0).to_dict())
# {'content_type': 'a', 'data': b'b', 'id': 'c'}
回答2:
You can get the dict
representation of a class object in python by using the vars method.
First, you need to implement __setattr__
inside the class. Add this method inside your class.
def __setattr__(self, name, value):
if value is not None:
self.__dict__[name] = value
if value is not None and name == 'upload_date':
self.__dict__[name] = value.isoformat()
This will prevent the None
fields from being added into the class dict.
>>> img = Image(content_type='something')
>>> vars(i)
{'content_type': 'something', 'data': b'', 'id': '', 'size': 0}
However, using dataclasses.asdict
will still keep the None
fields.
>>> import dataclasses
>>> img = Image(content_type='something')
>>> dataclasses.asdict(img)
{'content_type': 'something', 'data': b'', 'id': '', 'upload_date': None, 'size': 0}
But you can use vars
since that works. object.__dict__
returns the same thing as vars(object)
.
来源:https://stackoverflow.com/questions/57305749/how-to-create-dict-from-class-without-none-fields