Home > Blockchain >  expanding a dataclass of type list by an element
expanding a dataclass of type list by an element

Time:09-26

I have defined a dataclass which is a list and I want to expand it:

@dataclass
class ShoppingCart:
    item_id: list = None

@dataclass
class Purchase:
    items: dict = ShoppingCart

@dataclass
class Item:
    price: int = 0
    name: str = ""

so later on I put an item in the Shoppingcart:

if getattr(inst_of_Purchase, inst_of_ShoppingCart) == None: ##no item in cart
    setattr(inst_of_Purchase, inst_of_ShoppingCart, inst_of_Item)
else: ## add an item
    ***

What is the correct Syntax to append an item to get a structure like this:

Purchase_1: {ShoppingCart_1: [item_1, item_2 ...], 
             ShoppingCart_2: [item_123, item_2 ...]...}
    

CodePudding user response:

Here's how I would declare the models, using forward references so it's a bit easier to see the nested structure (top-down instead of bottom-up). If you want to go with a bottom-up approach as you initially had, you can swap the order you define the dataclasses and switch List['ShoppingCart'] to just List[ShoppingCart] for example.

from dataclasses import dataclass
from typing import List


@dataclass
class Purchase:
    carts: List['ShoppingCart'] = None


@dataclass
class ShoppingCart:
    # If you want default value to be an empty list:
    #  item: List['Item'] = dataclasses.field(default_factory=list)
    items: List['Item'] = None


@dataclass
class Item:
    price: int = 0
    name: str = ""

Then if we need to add items to a new purchase:

my_purchase = Purchase()

if my_purchase.carts is None:  # no item in cart
    item_1 = Item(name='first item')
    item_2 = Item(2, 'second item')

    my_cart = ShoppingCart(items=[item_1, item_2])
    my_purchase.carts = [my_cart]

else: ## add an item
    ...

print(my_purchase)
# Purchase(carts=[ShoppingCart(items=[Item(price=0, name='first item'), Item(price=2, name='second item')])])

Note that if you're on Python 3.9 (I wasn't sure if you are) you can remove the typing.List import, and use the built in list, as standard collections now support subscripted types. So for example, taken from the above:

carts: List['ShoppingCart'] = None

would become just (without the typing import):

carts: list['ShoppingCart'] = None
  • Related