初尝
Python 3.7 引入了一个新的模块,这个模块就是今天要试探的 dataclass
。dataclass
的用法和普通的类装饰器没有任何区别,它的作用是替换定义类的时候的:def __init__()
我们来看看如何使用它
# 我们需要引入 dataclass 包
from dataclasses import dataclass
@dataclass
class A:
a: int
b: int
c: str
d: str = "test"
a = A(1, 2, "3")
print(a)
我们执行这段代码,得到结果A(a=1, b=2, c='3', d='test')
可以看到,它的效果和
class A:
def __init__(self, a, b, c, d="test"):
self.a = a
self.b = b
self.c = c
self.d = d
a = A(1, 2, "3")
print(a)
完全一样!使用了 dataclass
可以省下很多代码,可以帮我们节约很多时间,代码也变得很简洁了。
如果有想学习python的程序员,可来我的python学习扣qun:711944363,免费送python的视频教程噢!我每晚上8点还会在群内直播讲解python知识,欢迎大家前来学习哦。
定义类型
我们发现,使用 dataclass
的时候,需要对初始化的参数进行类型定义,比如上面的例子里面,我为 a
, b
, c
, d
定义的类型分别是 int
, int
, str
和 str
。
那我建立实例的时候,传递非定义的类型的数据进去,会报错么?
答案是很明显的,是不会报错的,毕竟 python
是解释性语言嘛。
当然我们也要试试的
a = A("name", "age", 123, 123)
print(a)
得到结果A(a='name', b='age', c=123, d=123)
果然是不会报错的。
但是在 pycharm 之类的 IDE 里面,是会提醒修改的,这点很不爽
那么我们可以使用万能的类型的么?当然是可以的,但是不建议(毕竟现在都建议写 python
的工程师加上类型检查了)
做法如下:
@dataclass
class A:
a: ""
b: 1
这样就可以随意传参了。
我们只需要随意给一个字符串就可以了,也可以事任何的其他类型
继承
使用了 dataclass
之后,类的继承还是之前的那样么?
我们来试试
@dataclass
class A:
a: int
b: str
@dataclass
class B(A):
c: int
d: int
b = B(a=1, b="2", c=3, d=4)
就完了。
再来想想我们之前的继承 __init__
是怎么写的
class A:
def __init__(self, a: int, b: str):
self.a = a
self.b = b
class B(A):
def __init__(self, a: int, b: str, c: int, d: int):
super().__init__(a, b)
self.c = c
self.d = d
b = B(a=1, b="2", c=3, d=4)
一对比,是不是上面的代码简洁太多太多了!简直的优化利器!
使用 make_dataclass
快速创建类
除此之外,dataclasses
还提供了一个方法 make_dataclass
让我们可以快速创建类
from dataclasses import make_dataclass
A = make_dataclass(
"A",
[("a", int), "b", ("c", str), ("d", int, 1)],
namespace={'add_one': lambda self: self.a + 1})
这个和
@dataclass
class A:
a: int
b: ""
c: str
d: int = 1
def add_one(self):
self.a += 1
是完全一样的
尾言
我们只是初步的使用 dataclass
来替换了以往的 __init__
而已,还有很多新带入的东西没有使用,比如 field
还有其他的强大的功能。