Hướng dẫn python dataclass docstring
Source code: Lib/dataclasses.py Show This module provides a decorator and functions for automatically adding generated special methods such as The member variables to use in these generated methods are defined using PEP 526 type annotations. For example, this code: from dataclasses import dataclass @dataclass class InventoryItem: """Class for keeping track of an item in inventory.""" name: str unit_price: float quantity_on_hand: int = 0 def total_cost(self) -> float: return self.unit_price * self.quantity_on_hand will add, among other things, a def __init__(self, name: str, unit_price: float, quantity_on_hand: int = 0): self.name = name self.unit_price = unit_price self.quantity_on_hand = quantity_on_hand Note that this method is automatically added to the class: it is not directly specified in the New in version 3.7. Module contents¶@ dataclasses. dataclass (*,
init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False,
slots=False)¶This function is a decorator that is used to add generated special methods to classes, as described below. The The order of the fields in all of the generated methods is the order in which they appear in the class definition. The If @dataclass class C: ... @dataclass() class C: ... @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False, slots=False) class C: ... The parameters to
@dataclass class C: a: int # 'a' has no default value b: int = 0 # assign a default value for 'b' In this example, both def __init__(self, a: int, b: int = 0):
dataclasses. field (*, default=MISSING,
default_factory=MISSING, init=True, repr=True, hash=None, compare=True, metadata=None,
kw_only=MISSING)¶For common and simple use cases, no other functionality is required. There are, however, some dataclass features that require additional per-field information. To satisfy this need for additional information, you can replace the default field value with a call to the
provided @dataclass class C: mylist: list[int] = field(default_factory=list) c = C() c.mylist += [1, 2, 3] As shown above, the The parameters to
If the default value of a field is specified by a call to
@dataclass class C: x: int y: int = field(repr=False) z: int = field(repr=False, default=10) t: int = 20 The class attribute dataclasses. Field ¶
Other attributes may exist, but they are private and must not be inspected or relied on. dataclasses. fields (class_or_instance)¶Returns a tuple of dataclasses. asdict (obj, *,
dict_factory=dict)¶Converts the dataclass Example of using @dataclass class Point: x: int y: int @dataclass class C: mylist: list[Point] p = Point(10, 20) assert asdict(p) == {'x': 10, 'y': 20} c = C([Point(0, 0), Point(10, 4)]) assert asdict(c) == {'mylist': [{'x': 0, 'y': 0}, {'x': 10, 'y': 4}]} To create a shallow copy, the following workaround may be used: dict((field.name, getattr(obj, field.name)) for field in fields(obj))
dataclasses. astuple (obj, *,
tuple_factory=tuple)¶Converts the dataclass Continuing from the previous example: assert astuple(p) == (10, 20) assert astuple(c) == ([(0, 0), (10, 4)],) To create a shallow copy, the following workaround may be used: tuple(getattr(obj, field.name) for field in dataclasses.fields(obj))
dataclasses. make_dataclass (cls_name, fields, *, bases=(), namespace=None,
init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False, match_args=True, kw_only=False,
slots=False)¶Creates a new dataclass with name This function is not strictly required, because any Python mechanism for creating a new class with C = make_dataclass('C', [('x', int), 'y', ('z', int, field(default=5))], namespace={'add_one': lambda self: self.x + 1}) Is equivalent to: @dataclass class C: x: int y: 'typing.Any' z: int = 5 def add_one(self): return self.x + 1 dataclasses. replace (obj, /,
**changes)¶Creates a new object of the same type as The newly returned object is created by calling the Init-only variables without default values, if any exist, must be specified on the call to
It is an error for Be forewarned about how dataclasses. is_dataclass (obj)¶Return If you need to know if a class is an instance of a dataclass (and not a dataclass itself), then add a further check for
def is_dataclass_instance(obj): return is_dataclass(obj) and not isinstance(obj, type) dataclasses. MISSING ¶A sentinel value signifying a missing default or default_factory. dataclasses. KW_ONLY ¶A sentinel value used as a type annotation. Any fields after a pseudo-field with the type of In this example, the fields @dataclass class Point: x: float _: KW_ONLY y: float z: float p = Point(0, y=1.5, z=2.0) In a single dataclass, it is an error to specify more than one field whose type is New in version 3.10. exceptiondataclasses. FrozenInstanceError ¶Raised when an implicitly defined Post-init processing¶The generated Among other uses, this allows for initializing field values that depend on one or more other fields. For example: @dataclass class C: a: float b: float c: float = field(init=False) def __post_init__(self): self.c = self.a + self.b The @dataclass class Rectangle: height: float width: float @dataclass class Square(Rectangle): side: float def __post_init__(self): super().__init__(self.side, self.side) Note, however, that in general the dataclass-generated See the section below on init-only variables for ways to pass parameters to Class variables¶One of two places where
Init-only variables¶The other place where
For example, suppose a field will be initialized from a database, if a value is not provided when creating the class: @dataclass class C: i: int j: int = None database: InitVar[DatabaseType] = None def __post_init__(self, database): if self.j is None and database is not None: self.j = database.lookup('j') c = C(10, database=my_database) In this case,
Frozen instances¶It is not possible to create truly immutable Python objects. However, by passing There is a tiny performance penalty when using Inheritance¶When the dataclass is being created by the @dataclass class Base: x: Any = 15.0 y: int = 0 @dataclass class C(Base): z: int = 10 x: int = 15 The final list of fields is, in order, The generated def __init__(self, x: int = 15, y: int = 0, z: int = 10): Re-ordering of keyword-only parameters in __init__()¶After the parameters needed for In
this example, @dataclass class Base: x: Any = 15.0 _: KW_ONLY y: int = 0 w: int = 1 @dataclass class D(Base): z: int = 10 t: int = field(kw_only=True, default=0) The generated def __init__(self, x: Any = 15.0, z: int = 10, *, y: int = 0, w: int = 1, t: int = 0): Note that the parameters have been re-ordered from how they appear in the list of fields: parameters derived from regular fields are followed by parameters derived from keyword-only fields. The relative ordering of keyword-only parameters is maintained in the
re-ordered Default factory functions¶
Mutable default values¶
Descriptor-typed fields¶Fields that are assigned descriptor objects as their default value have the following special behaviors:
class IntConversionDescriptor: def __init__(self, *, default): self._default = default def __set_name__(self, owner, name): self._name = "_" + name def __get__(self, obj, type): if obj is None: return self._default return getattr(obj, self._name, self._default) def __set__(self, obj, value): setattr(obj, self._name, int(value)) @dataclass class InventoryItem: quantity_on_hand: IntConversionDescriptor = IntConversionDescriptor(default=100) i = InventoryItem() print(i.quantity_on_hand) # 100 i.quantity_on_hand = 2.5 # calls __set__ with 2.5 print(i.quantity_on_hand) # 2 Note that if a field is annotated with a descriptor type, but is not assigned a descriptor object as its default value, the field will act like a normal field. |