Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pythonic way to check if a dataclass field has a default value

I've been using python 3.7 lately and was looking for ways to leverage the new dataclasses. Basically I had a method that iterates over the dataclass fields and checks if they have a default value:

from dataclasses import fields, MISSING

@classmethod
def from_json(cls)
    datacls_fields = fields(cls)
    for field in datacls_fields:
        if  (field.default != MISSING):
            #...

However in the official documentation, it says:

MISSING value is a sentinel object used to detect if the default and default_factory parameters are provided. This sentinel is used because None is a valid value for default. No code should directly use the MISSING value.

Anyone knows a better/more pythonic way to do it?

like image 543
addonis1990 Avatar asked Dec 03 '18 08:12

addonis1990


People also ask

What is __ Post_init __?

Modifying fields after initialization with __post_init__ The __post_init__ method is called just after initialization. In other words, it is called after the object receives values for its fields, such as name , continent , population , and official_lang .

What does @dataclass do in Python?

Python introduced the dataclass in version 3.7 (PEP 557). The dataclass allows you to define classes with less code and more functionality out of the box.

Can Python Dataclass 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 is @dataclass?

A data class is a class typically containing mainly data, although there aren't really any restrictions. It is created using the new @dataclass decorator, as follows: from dataclasses import dataclass @dataclass class DataClassCard: rank: str suit: str.


1 Answers

This is the definition of MISSING in python source code in dataclasses.py:

# A sentinel object to detect if a parameter is supplied or not.  Use
# a class to give it a better repr.
class _MISSING_TYPE:
    pass
MISSING = _MISSING_TYPE()

The definition is pretty clear, its use case is only to check if a parameter has been supplied or not, and make a distinction between a value of None and an unsupplied value :

def my_func(a=MISSING):
    if a is not MISSING:
        # a value has been supplied, whatever his value

So it is perfectly ok to use it in your code for value comparison. By telling No code should directly use the MISSING value they just warn us that this variable has no specific usage (other that for comparison) and should not be used in the code to avoid unexpected behavior.

You should update your code to use a more pythonic syntax is not MISSING :

from dataclasses import fields, MISSING

@classmethod
def from_json(cls)
    datacls_fields = fields(cls)
    for field in datacls_fields:
        if field.default is not MISSING:

like image 118
Charlesthk Avatar answered Sep 16 '22 13:09

Charlesthk