Python 中的类装饰器

本文用于记录在使用 Python 过程中不知道的类装饰器的用法与功能。

@dataclass

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
"""Add dunder methods based on the fields defined in the class.

Examines PEP 526 __annotations__ to determine fields.

If init is true, an __init__() method is added to the class. If repr
is true, a __repr__() method is added. If order is true, rich
comparison dunder methods are added. If unsafe_hash is true, a
__hash__() method is added. If frozen is true, fields may not be
assigned to after instance creation. If match_args is true, the
__match_args__ tuple is added. If kw_only is true, then by default
all fields are keyword-only. If slots is true, a new class with a
__slots__ attribute is returned.
"""

根据类中字段的定义,给类添加魔法方法:

  • 如果 init 为 True,则会为类添加一个 __init__() 方法
  • 如果 repr 为 True,则会添加一个 __repr__() 方法
  • 如果 order 为 True,则会添加用于大小比较的魔法方法
  • 如果 unsafe_hash 为 True,则会添加一个 __hash__() 方法
  • 如果 frozen 为 True,则在实例创建后,不允许修改字段的值
  • 如果 match_args 为 True,则会添加 __match_args__ 元组
  • 如果 kw_only 为 True,则默认所有字段都是仅限关键字参数
  • 如果 slots 为 True,则会返回一个带有 __slots__ 属性的新类

@dataclass 的声明如下:

在不传入参数的情况下,默认会增加 3 个魔法方法:

  1. __init__()
  2. __repr__()
  3. __eq__()

示例如下:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
from dataclasses import dataclass

@dataclass
class Student:
    name: str
    age: int

student = Student(name="Joe", age=28)
print(student.__repr__()) # Student(name='Joe', age=28)

student2 = Student(name="Joe", age=28)
print("equal:", student == student2) # equal: True