Home  >  Article  >  Backend Development  >  How are data classes used in Python?

How are data classes used in Python?

WBOY
WBOYforward
2023-04-23 17:22:071459browse

Python3.7 introduced dataclass. The dataclass decorator can declare a Python class as a data class; a data class is suitable for storing data. Generally speaking, it has the following characteristics:

  • A data class represents a certain data type, and a data object represents An entity of a specific class that contains the entity's properties.

  • Objects of the same type can be compared; for example, greater than, less than, or equal to.

Data class definition

By its nature, there is nothing special about data classes, except that the @dataclass decorator automatically generates __repr__, init, __eq__ and a series of methods. Define data class:

from dataclasses import dataclass

@dataclass
class A:
  normal: str
  defVal: int = 0

Decorator

The complete form of dataclass is (True is to generate the corresponding method, False will not generate it; if the corresponding method has been defined in the class, this parameter is ignored):

@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False):

  • init: Will be generated by default __init__ method;

  • repr: The __repr__ method will be generated by default; the repr string contains the class name, each field name and its repr (in the order defined in its class);

  • eq: The __eq__ method will be generated by default; if False is passed in, the __eq__ method will not be added by dataclass, but will inherit object.__eq__ (compare id);

  • order: __gt__, __ge__, __lt__, __le__ methods are not generated by default;

  • unsafe_hash: If it is False (default), then Generates the __hash__() method (used by the built-in hash()) based on how eq and frozen are set.

    • If eq and frozen are both true, a __hash__() method will be generated by default;

    • If eq is true while frozen is false, __hash__() will be set to None, marking it as unhashable (which it is, since it is mutable);

    • If eq is If false, __hash__() will remain unchanged, meaning that the superclass's __hash__() method will be used (fallback to id-based hashing if the superclass is object).

  • frozen: If true, the properties cannot be modified after the instance is initialized;

field

Pass field Method, customizable attributes:
dataclasses.field(*, default=MISSING, default_factory=MISSING, repr=True, hash=None, init=True, compare=True, metadata=None):

  • default: If provided, this will be the default value for this field.

  • default_factory: used to specify fields with variable default values. It must be a callable object without parameters; mutually exclusive with default (cannot be specified at the same time).

  • init: If true (the default), the field is included as a parameter in the generated __init__() method.

  • repr: If true (the default), the field is included in the generated string returned by the __repr__() method.

  • compare: If true (the default), the field is included in the generated equality and comparison methods (__eq__(), __gt__(), etc.).

  • hash: Can be a Boolean or None:

  • is None (default), the value of compare is used, which is usually expected behavior (setting this value to anything other than None is discouraged);

  • is true, then this field is included in the generated __hash__() method;

  • One possible reason for setting hash=False but compare=True (that is, excluding a field from the hash but still using it for comparison) is that calculating the hash of the field is very expensive;

  • metadata: This can be a map or None; None is treated as an empty dictionary. This value is contained in MappingProxyType(), making it read-only and exposed on the Field object (provided as a third-party extension mechanism).

Use default_factory to generate default value:

from dataclasses import dataclass, field
import random

def build_marks() -> list:
    return [random.randint(0, 1000) for i in range(5)]

@dataclass(order=True)
class RandMark:
    marks: list = field(default_factory=build_marks)

r = RandMark() # 使用build_marks生成默认值
print(r)

Initialization

Class modified by dataclass decorator:

  • No need to define __init__, dataclass will handle it automatically;

  • Pre-define member attributes (and type hints) in an easy-to-read manner; and define default values;

  • dataclass will automatically add a __repr__ function;

Data comparison

Comparison can be automatically added through @dataclass(order = True) Methods (__eq__ and __lt__):

Comparison is done through tuples generated by attributes (fields); as above, the comparison tuple is (normal, defVale)
By compare=False, you can Set fields that are not used for comparison:

@dataclass(order=True)
class Student:
    name: str = field(compare=False)
    score: float

s = [Student("mike", 90),
    Student("steven", 80),
    Student("orange", 70)
    ]
print(sorted(s)) # 只根据score排序

Post-processing

Post-processing can be done through __post_init__ (automatically called before __init__ returns):

from dataclasses import dataclass

@dataclass
class FloatNumber:
    val: float
    decimal: float = 0
    integer: float = 0

    def __post_init__(self):
        self.decimal, self.integer = math.modf(self.val)

f = FloatNumber(1.2) # decimal与integer自动赋值

dataclasses method

dataclasses built-in properties and methods:

  • fields(class_or_instance): Returns a tuple of field Field objects;

  • asdict(instance, *, dict_factory=dict): Convert data class to dictionary, (name:value) pair;

  • astuple(instance, *, tuple_factory=tuple): Convert The data class is converted into a tuple;

  • replace(instance, **changes): Create a new object of the same type as instance, and changes is the value to be modified.

The above is the detailed content of How are data classes used in Python?. For more information, please follow other related articles on the PHP Chinese website!

Statement:
This article is reproduced at:yisu.com. If there is any infringement, please contact admin@php.cn delete