当Python 3.7发布时,为了更容易地定义更多的标准类,新的@dataclass装饰器引入了一种称为“数据类”的Python类。数据类是一种类,仅仅是为了存储数据,因此在Python编程语言中很常见。 在这篇文章中,我们将学习关于Python3.7中@dataclass装饰器的用法。
为什么使用@dataclass
在Python中,当你需要创建一个只存储数据的类时,这些属性没有需要自定义的方法或特殊的行为,这意味着我们使用默认的__init__方法、__str__方法等常规Python魔法方法。在这种情况下,通过使用@dataclass,您可以将您的代码缩写为少量几行,使程序更加简洁。
@dataclass装饰器带来了很多好处,比如:
- 不再需要编写复杂的__init__或__repr__方法。
- 更方便的访问属性。
- 默认实现了__eq__方法,所以可以方便地进行对象比较和判断是否相等等操作。
如何使用@dataclass
要使用@dataclass,您需要在引入了dataclasses包之后,利用@dataclass装饰器来装饰一个类。
基本用法
下面是一个简单的使用@dataclass的例子:
from dataclasses import dataclass
@dataclass
class Employee:
name: str
age: int
designation: str
salary: float
以上代码中我们使用了@dataclass装饰器来修饰一个名为Employee的类。它至少需要一个参数(变量名),即要在这个类中存储的属性。
需要注意的是,这里的name、age、designation和salary都没有类型注释。但是用dataclass时,类型已经在声明中指定。这些注释将自动放入类定义中。
高级用法
假设我们有一个类Book,我们想为它添加一个属性,该属性默认为1,每次设置为新值时加1。我们可以通过装饰器的parameters进一步指定属性,以及其他更高级的特性。看下面的例子:
@dataclass(order=True)
class Book:
title: str
price: int
pub_year: int
edition: int = 1
def __post_init__(self):
self.edition += 1
def increase_price(self, percent_increase):
self.price *= 1 + percent_increase / 100
我们在这个例子中指定了以下参数:
- order=True:启用排序,默认情况下关闭排序。
- edition: int = 1:指定默认值。
- post_init:后期初始化程序,与__init__不同;在初始化对象后自动调用。
派生数据类
派生数据类是一种继承数据类的XML子类。为了派生数据类,我们将@dataclass装饰器应用到标准类声明中并定义类型注释。
在下面的示例中,我们还创建了一个基类Person,在一个数据类Student中继承它。
@dataclass
class Person:
name: str
id: int
address: str
salary: float = 0.0
@dataclass
class Student(Person):
institution: str
average: float
在以上代码中,标准类Person被表示为数据类。此外,我们定义了派生数据类Student,它派生自Person,其中还声明institution和average作为属性。
示例
最后我们再来看两个例子。
骰子游戏
假设我们要编写一个骰子游戏,需要维护一个骰子的数据,包括骰子的面数和点数等信息。我们可以使用@dataclass来管理数据,如下所示:
from dataclasses import dataclass
import random
@dataclass
class Die:
sides: int
value: int = 1
def roll(self):
self.value = random.randint(1, self.sides)
上面的代码定义了一个名为Die的类,它派生自包含两个属性sides和value的数据类。在增加一种roll方法后,该类可以模拟掷骰子的行为,即随机选择1到sides之间的一种面。现在,我们可以创建一个六面的骰子并进行投掷:
my_die = Die(sides=6)
print(my_die.value)
my_die.roll()
print(my_die.value)
运行结果可能是这样的:
1
4
账户系统
下面我们再来看一个简单的账户系统,使用@dataclass轻松管理用户信息:
from dataclasses import dataclass
@dataclass
class Account:
owner: str
balance: float = 0.0
def deposit(self, amount: float):
self.balance += amount
def withdraw(self, amount: float):
if amount > self.balance:
raise ValueError('Insufficient balance')
self.balance -= amount
def __str__(self):
return f'{self.owner} has {self.balance:.2f} in the account'
上述代码定义了一个名为Account的类,它包含两个数据属性:owner和balance。此外,它还提供了两个方法deposit和withdraw,用于将资金存入或从此账户中提取。现在,我们可以创建一个名为Tom的帐户,初始余额为200:
my_account = Account('Tom', 200.0)
print(my_account)
my_account.deposit(50)
print(my_account)
my_account.withdraw(100)
print(my_account)
运行结果可能是这样的:
Tom has 200.00 in the account
Tom has 250.00 in the account
Tom has 150.00 in the account
在这个例子中,我们定义了名为Account的数据类,并定义了一些方法,用于管理一个账户的余额和存款等信息。这使得在创建新账户时,我们可以轻松地使用@dataclass管理数据。
本站文章如无特殊说明,均为本站原创,如若转载,请注明出处:Python3.7 新特性之dataclass装饰器 - Python技术站