在 Python3 中使用类型提示初始化 Optional Dict 的正确方法?
Correct way to initialize an Optional Dict with type hint in Python3?
我想用类型提示(键应该是字符串,值应该是另一个数据类的实例)初始化一个数据类字典,称为usr_orders
,不需要用户在初始化实例时初始化。根据我的理解 Optional
是 union(.., 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)
我想用类型提示(键应该是字符串,值应该是另一个数据类的实例)初始化一个数据类字典,称为usr_orders
,不需要用户在初始化实例时初始化。根据我的理解 Optional
是 union(.., 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
只是添加到 __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)