Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to use dataclasses to generate a field value?

I have the following class:

class WordItem:
    def __init__(self, phrase: str, word_type: WORD_TYPE):
        self.id = f'{phrase}_{word_type.name.lower()}'
        self.phrase = phrase
        self.word_type = word_type
        @classmethod

    def from_payload(cls, payload: Dict[str, Any]) -> 'WordItem':
        return cls(**payload)

How can I rewrite this class as a dataclass?

Specifically, how should the id field be declared? It has a generated value, and is not a field that the code creating instances would provide.

like image 851
petrush Avatar asked Oct 03 '18 13:10

petrush


People also ask

How do Dataclasses work in python?

The dataclass allows you to define classes with less code and more functionality out of the box. This Person class has the __init__ method that initializes the name and age attributes. If you want to have a string representation of the Person object, you need to implement the __str__ or __repr__ method.

Can python Dataclasses have methods?

A dataclass can very well have regular instance and class methods. Dataclasses were introduced from Python version 3.7. For Python versions below 3.7, it has to be installed as a library.

What are Dataclasses in python?

dataclass module is introduced in Python 3.7 as a utility tool to make structured classes specially for storing data. These classes hold certain properties and functions to deal specifically with the data and its representation. Although the module was introduced in Python3.


Video Answer


1 Answers

Just move each of your attributes to a type-annotated declaration on the class, where the class has been decorated with the @dataclasses.dataclass decorator.

You can generate the value for id in a __post_init__ method; make sure you mark it as exempt from the __init__ arguments with a dataclass.field() object:

from dataclasses import dataclass, field    

@dataclass
class WordItem:
    id: str = field(init=False)
    phrase: str
    word_type: WORD_TYPE

    def __post_init__(self):
        self.id = f'{self.phrase}_{self.word_type.name.lower()}'

Demo:

>>> from types import SimpleNamespace
>>> wt = SimpleNamespace(name='Python')
>>> WordItem('await', wt)
WordItem(id='await_python', phrase='await', word_type=namespace(name='Python'))
like image 101
Martijn Pieters Avatar answered Sep 22 '22 14:09

Martijn Pieters