Могу ли я иметь дополнительный параметр в классах данных, который опускается при преобразовании в dict?
Я хочу выполнить статическую проверку типа (pylance
в vscode
) в некоторых словарях. "Сложная" часть - это то, что я хочу, чтобы некоторые параметры были необязательными и вообще не отображались в словаре. Я пробовал использоватьdataclasses
а также TypedDict
но пока безуспешно.
from typing import Optional, List
from dataclasses import dataclass, asdict
@dataclass
class SubOrder:
name: str
@dataclass
class Order:
name: str
sub_orders: Optional[List[SubOrder]]
assert asdict(Order(name="Pizza")) == {"name": "Pizza"}
assert asdict(Order(name="Pizza", sub_orders=[SubOrder(name="Pasta")])) == {
"name": "Pizza",
"sub_orders": [{"name": "Pasta"}],
}
Это достижимо с dataclasses
? Я просто хочу, чтобы моя проверка статического типа (pylance
/ pyright
), чтобы проверить свои словари, поэтому я использую dataclasses
. Я пробовал сTypedDict
также, но средства проверки типов, похоже, не ведут себя так, как я. Они всегда требуют, чтобы я установилsub_orders
.
Следующий код проходит, но pylance
не доволен отсутствием sub_orders
.
from typing import Optional, List, TypedDict
class SubOrder(TypedDict):
name: str
class Order(TypedDict):
name: str
sub_orders: Optional[List[SubOrder]]
assert Order(name="Pizza") == {"name": "Pizza"}
assert Order(name="Pizza", sub_orders=[SubOrder(name="Pasta")]) == {
"name": "Pizza",
"sub_orders": [{"name": "Pasta"}],
}
РЕДАКТИРОВАТЬ
Я добавил отчет об ошибке вpylance
так как это может быть ошибка в pylance
/ pyright
2 ответа
from dataclasses import asdict, dataclass
from typing import List, Optional
from validated_dc import ValidatedDC
@dataclass
class SubOrder(ValidatedDC):
name: str
@dataclass
class Order(ValidatedDC):
name: str
sub_orders: Optional[List[SubOrder]] = None
def as_dict(self):
data = asdict(self)
return {key: value for key, value in data.items() if value is not None}
data = {'name': 'pizza'}
order = Order(**data)
assert order.get_errors() is None
assert asdict(order) == {'name': 'pizza', 'sub_orders': None}
assert order.as_dict() == {'name': 'pizza'}
data = {'name': 'pizza', 'sub_orders': [{'name': 'pasta'}]}
order = Order(**data)
assert order.get_errors() is None
assert asdict(order) == {'name': 'pizza', 'sub_orders': [{'name': 'pasta'}]}
assert isinstance(order.sub_orders[0], SubOrder)
ValidatedDC - https://github.com/EvgeniyBurdin/validated_dc
Вы можете иметь необязательный параметр в классе данных, установив его в пустую строку, например:
from dataclasses import dataclass
@dataclass
class SubOrder:
name: str=""