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

Time:11-01

I want to initialize a dataclass dictionary with type hint(key should be string, the value should be another dataclass's instances) called usr_orders that does NOT require user init upon initializing instances. Based on my understanding Optional is the union(.., None), so I went with:

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

But when I try to modify it using key-value I got the following error: 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

This error seems to be caused by the optional Dict definition. But I don't know how to solve this. Does anyone know why I cannot update the usr_orders? Thanks!

CodePudding user response:

You'll need to import a field and use a 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)

Part of the issue is that you were using Dict as a default field for the data class. Dict is a type hint; I think you were meaning to use dict() or {} - however, this would not work. Try it and see for yourself! You'll end up with this error: ValueError: mutable default <class 'dict'> for field usr_orders is not allowed: use default_factory. This is a dataclass thing where it prevents you from using 1 dictionary for multiple instances.

Further reading

CodePudding user response:

Youre using:

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

instead of:

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

replace = by :

  • Related