持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第7天,点击查看活动详情
简单回归一下上一次,我们介绍 python 提供 dataclasses 中的 dataclass 可以帮助我们装饰器形式来创建一个数据类,这样做好处大大简化了我们工作,然后有介绍 field 和 default_factory 可以帮助通过指定一个函数来为一些属性指定默认值
如何将某一个字段从初始化函数移除
id:str = field(init=False,default_factory=generate_id)
方法比较简单就是给 field 的 init 参数设置为 False 即可,这样当你试图在初始化一个 Tut 的实例时给出 id 的初始值就会看到下面提示
tut = Tut("hidden markov model","machine_learning",id='abc123')
TypeError: __init__() got an unexpected keyword argument 'id'
如何在初始化后利用字段来为某一个字段进行自动赋值
search_string:str = field(init=False)
这里为 Tut 类添加一个 search_string,这个字段通常根据实例中某些字段值来在数据库中进行搜索,例如使用 title 和 category 值,来在数据库上搜索某一个对应数据的记录,那么首先搜索语句是不允许用户输入的,所以这里指定 init=False 来禁止用户输入,不过需要做的是在一些字段有了值,也就是在初始化之后,我们就可以为这个 search_string 进行赋值了,好了那么应该怎么做呢?
可以在 __post_init__ 这个函数中去给 search_string 这个字段进行赋值,代码如下
def __post_init__(self) -> None:
self.search_string = f"{self.title} {self.category}"
Tut(title='hidden markov model', category='machine_learning', isCompleted=True, email_addresses=[], id='BPYSUJSNNQZZ', search_string='hidden markov model machine_learning')
私有变量
对于类来说,有时候有些字段是对于用户,也就是类调用者是不可见,或者说这些字段是不允许调用者随意修改,那么在 python 中可以显示方式,在这一点上有点类似于 js 做法,就是通过字段名前加上一个下划线来表示该字段是私有属性,例如 search_string 前加上一个下划线 _search_string 就变成了私有属性。
Tut(title='hidden markov model', category='machine_learning', isCompleted=True, email_addresses=[], id='EUFRNVPXCCDV', _search_string='hidden markov model machine_learning')
其实既然已经是私有属性,那么自然也不想在 print 将其输出,那么应该如何将其从 print 显示出信息中将其移除呢,其实也很简单,只要将其 field 添加 repr=False 即可
search_string:str = field(init=False,repr=False)
Tut(title='hidden markov model', category='machine_learning', isCompleted=True, email_addresses=[], id='VUHVWTLSDDJN')
不可变数据
我们都知道在开发中通常 mutable 和 immutable,这些概念我是在学习函数式编程时接触到,在其他语言中提供 const 这个修饰符来定义一个 immutable 数据,也就是静态变量,也就是一旦创建为变量赋值后,随后就无法修改这个变量值,其实这是我们想要的确定性,好处多多,做过编程都不会不然而喻其好处。
def main()->None:
# random_id = generate_id()
# print(random_id)
tut = Tut("hidden markov model","machine_learning")
tut.title = "Probabilistic Graphical Models"
print(tut)
可以这样方式随意修改 Tut 实例的字段,不过我们提供在装饰器中将 forzen指定为 True 的值,这样就在初始化类后无法在随意修改其属性值了
@dataclass(frozen=True)
到此为止我们已经介绍过来一些关于如何使用 dataclasses 提供方法来有效地定义一个数据类,接下里会介绍一些 3.10 中提供的关于 dataclasses 的新特性。