Python数据类教程展示了如何在自定义类中使用Python中的数据类装饰器。数据类装饰器有助于减少一些样板代码。
Python数据类装饰器
dataclass装饰器用于自动生成类的特殊方法,包括__str__和__repr__。它有助于减少一些样板代码。dataclass装饰器位于dataclasses模块中。
dataclass装饰器检查类以查找字段。字段被定义为具有类型注释的类变量。
@dataclass class Test: ... @dataclass() class Test: ... @dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False) class Test: ...
这三个声明是等价的。如果没有在装饰器中设置参数,则使用默认参数。如果init参数设置为True,将生成__init__方法。如果类已经定义了__init__,则忽略该参数。如果repr参数设置为True,则__repr__将生成方法。如果该类已经定义了__repr__,则该参数将被忽略。如果eq参数设置为True,将生成__eq__方法。如果该类已经定义了__eq__,则忽略此参数。
如果order参数设置为True,则__lt__、__le__、__gt__和__ge__方法被生成。如果该类已经定义了任何方法,则引发ValueError。如果unsafe_hash定义为False,则__hash__方法根据eq和frozen的设置生成。如果frozen参数设置为True,则对字段的赋值将产生异常。
Python常规自定义类
在常规的自定义Python类中,我们手动提供构造函数和其他方法,例如__repr__。
#!/usr/bin/python
class Person:
def __init__(self, name, age):
self.name = name
self.age = age
def __repr__(self):
return f'Person{{name: {self.name}, age: {self.age}}}'
p = Person('John Doe', 34)
print(p)
该示例显示了一个带有构造函数和__repr__方法的Person类,它给出了对象的完整表示。
$ ./regular_class.py
Person{name: John Doe, age: 34}
Python数据类示例
以下示例显示了dataclass装饰器的简单用法。
#!/usr/bin/python
from dataclasses import dataclass
@dataclass
class Person:
name: str
age: int
p = Person('John Doe', 34)
print(p)
我们有一个包含两个字段的类:name和str。
from dataclasses import dataclass
dataclass装饰器位于dataclasses模块中。
@dataclass
class Person:
name: str
age: int
我们在Person类上应用dataclass装饰器。
p = Person('John Doe', 34)
print(p)
创建了一个新的人物对象。它的__init__方法被调用,该方法由dataclass装饰器自动生成。
$ ./simple_dataclass.py Person(name='John Doe', age=34)
Python数据类默认值
可以为字段提供默认值。
#!/usr/bin/python
from dataclasses import dataclass
@dataclass
class Person:
name: str = 'unknown'
age: int = 0
p = Person('John Doe', 34)
print(p)
p2 = Person()
print(p2)
在示例中,Person类有两个字段;这些字段有一些默认值。
@dataclass
class Person:
name: str = 'unknown'
age: int = 0
使用赋值运算符(=),我们为字段提供默认值。
p2 = Person() print(p2)
当我们不在构造函数中提供值时,字段将具有默认值。
$ ./default_values.py Person(name='John Doe', age=34) Person(name='unknown', age=0)
数据类冻结参数
如果frozen参数设置为True,我们就不能给字段赋值。
#!/usr/bin/python
from dataclasses import dataclass
@dataclass(frozen=True)
class Person:
name: str
age: int
p = Person('John Doe', 34)
p.occupation = 'gardener'
print(p)
print(p.occupation)
在示例中,frozen参数设置为True。该程序失败并显示以下错误消息:dataclasses.FrozenInstanceError:cannotassigntofield'occupation'。
数据类asdict函数
asdict函数将数据类实例转换为其字段的adict。
#!/usr/bin/python
from dataclasses import dataclass, asdict
@dataclass
class Person:
name: str
occupation: str
age: int
p = Person('John Doe', 'gardener', 34)
print(p)
print(asdict(p))
在示例中,我们借助asdict函数打印Person类的字段。
$ ./as_dict_fun.py
Person(name='John Doe', occupation='gardener', age=34)
{'name': 'John Doe', 'occupation': 'gardener', 'age': 34}
第一行是__repr__方法的输出,第二行是字段字典。
数据类字段函数
使用field函数,我们可以提供一些额外的每个字段信息。
#!/usr/bin/python
from dataclasses import dataclass, field
@dataclass
class Person:
name: str
age: int
occupation: str = field(init=False, repr=False)
p = Person('John Doe', 34)
print(p)
p.occupation = "Gardener"
print(f'{p.name} is a {p.occupation}')
在示例中,我们有一个额外的occupation字段。
occupation: str = field(init=False, repr=False)
occupation字段不包含在__init__和__repr__方法中。
$ ./fields.py Person(name='John Doe', age=34) John Doe is a Gardener
具有模式匹配的Python数据类
下一个示例使用具有模式匹配语法的数据类。
#!/usr/bin/python
from dataclasses import dataclass
@dataclass
class Point:
x: int
y: int
def check(p):
match p:
case Point(x=0, y=0):
print("Origin")
case Point(x, y) if y == 0:
print(f"on x axis")
case Point(x, y) if x == 0:
print(f"on y axis")
case Point(x, y) if x > 0 and y > 0:
print("Q I")
case Point(x, y) if x < 0 and y > 0:
print("Q II")
case Point(x, y) if x < 0 and y < 0:
print("Q III")
case Point(x, y) if x > 0 and y < 0:
print("Q IV")
case _:
print("Not a point")
points = [Point(3, 0), Point(0, 0), Point(-4, -5), Point(-4, 0), Point(0, 5),
Point(4, 8), Point(-5, 3), Point(6, -4)]
for p in points:
check(p)
我们有一个Point对象列表。使用match/case关键字,我们将每个点分配给原点、x和y轴,或四个象限之一。
case Point(x=0, y=0):
print("Origin")
在这种情况下,我们匹配具有x=0和y=0坐标的点。
case Point(x, y) if x > 0 and y > 0:
print("Q I")
使用守卫,我们检查该点是否位于第一象限。
$ ./points.py on x axis Origin Q III on x axis on y axis Q I Q II Q IV
在本教程中,我们使用了Python数据类装饰器。
列出所有Python教程。
