在 Python3 中使用类型提示初始化 Optional Dict 的正确方法?

Correct way to initialize an Optional Dict with type hint in Python3?

我想用类型提示(键应该是字符串,值应该是另一个数据类的实例)初始化一个数据类字典,称为usr_orders,不需要用户在初始化实例时初始化。根据我的理解 Optionalunion(.., None),所以我选择了:

@dataclass
class User:
    usr_orders: Optional[Dict[str, BookOrder]] = Dict

但是当我尝试使用键值修改它时出现以下错误:TypeError: '_GenericAlias' object does not support item assignment

def update_usr_orders(self, book_order:BookOrder):
    self.usr_orders[book_order.order_id] = book_order # book_order: BookOrder is a dataclass instance

这个错误似乎是由可选的字典定义引起的。但我不知道如何解决这个问题。有谁知道为什么我不能更新 usr_orders?谢谢!

您正在使用:

usr_orders = Optional[Dict[str, BookOrder]] = Dict

而不是:

usr_orders: Optional[Dict[str, BookOrder]] = Dict

=替换为:

您需要导入一个字段并使用 default_factory:

from dataclasses import dataclass, field
from typing import Optional, Dict

@dataclass
class BookOrder():
    id: str

@dataclass
class User:
    usr_orders: Optional[Dict[str, BookOrder]] = field(default_factory=dict)

    def update_usr_orders(self, book_order:BookOrder):
        self.usr_orders[book_order.id] = book_order

a = BookOrder('1')
u = User()
u.update_usr_orders(a)
print(u.usr_orders)

部分问题是您使用 Dict 作为数据 class 的默认字段。 Dict 是类型提示;我认为您的意思是使用 dict(){} - 但是,这是行不通的。试试看吧!您最终会遇到此错误:ValueError: mutable default <class 'dict'> for field usr_orders is not allowed: use default_factory。这是一个数据class 的东西,它阻止你对多个实例使用 1 个字典。

Further reading

只是添加到 ,注意在 Python 3.7+ 中,您还可以使用通过 __future__ 导入提供的新式注释来声明数据类。在这种情况下,这应该允许您取消 typing 导入。

from __future__ import annotations  # This can be removed in Python 3.10+

from dataclasses import dataclass, field


@dataclass
class BookOrder:
    id: str


@dataclass
class User:
    usr_orders: dict[str, BookOrder] | None = field(default_factory=dict)

    def update_usr_orders(self, book_order: BookOrder):
        self.usr_orders[book_order.id] = book_order


a = BookOrder('1')
u = User()
u.update_usr_orders(a)
print(u.usr_orders)