首页 > 其他分享 >dataclass装饰器

dataclass装饰器

时间:2022-09-07 20:23:45浏览次数:75  
标签:__ 初始化 field init dataclass 默认值 装饰

简介

根据定义dataclass时指"一个带有默认值的可变的namedtuple"
简单来说,就是你定义一个很普通的类,@dataclass装饰器可以
帮你生成__repr__、__init__等方法,就不用自己写一遍了。但是
此装饰器返回的依然是一个class类,这意味着并没有带来任何不便,
你依然可以使用继承、metaclass、docstring、定义方法等。

示例,解决实例化,__init__参数过多时的问题

from dataclasses import dataclass
@dataclass
class InventoryItem:
  name: str
  unit_price: float
  quantity_on_hand: int = 0  # 默认值为0

  def total_cost(self) -> float:
      return self.unit_price * self.quantity_on_hand

上面的代码会自动帮我们生成__init__初始化方法

示例,优雅的方式表示嵌套

from dataclasses import dataclass
from typing import List

@dataclass
class Player:
  name: str
  number: int
  position: str
  age: int

@dataclass
class Team:
  name: str
  players: List[Player]

james = Player('jack', 23, 'SF', 25)
james = Player('Nick', 3, 'PF', 21)

lal = Team([james, davis])
print(lal.name, lal.players)

示例,对象初始化后禁止改变

from dataclasses import dataclass
from typing import Any

@dataclass(forzen=True) # 这个参数在对象初始化后,会禁止更改值
class Data:
  name: Any
  value: Any = 42

data = Data('my_name', 99)
data.name = 'other' # 报错

示例,使用工厂函数为属性的默认值定义为空列表

from dataclasses import dataclass, field
from typing import List

@dataclass
class C:
  my_list: List[int] = field(default_factory=list)

c1 = C()
c1.my_list += [1,2,3]
c2 = C()

示例,使用field不初始化某个属性的值(因为默认的会初始化每个属性的值)

from dataclasses import dataclass, field
@dataclass
class C:
  a: float
  b: float
  c: float = field(init=False) # 告诉dataclass先不初始化成员变量c

c1 = C(10, 20)
print(c1.a, c1.b)

介绍field

通过上面的两个例子,我们认识到了field的两个作用:

在初始化可变默认值(mutable default) 情况下,必须要通过field的默认工厂函数来进行声明。
可以通过field来控制某一个成员变量是否被初始化。
下面我们详细介绍一下field的工作流程。
dataclass装饰器的工作流程:

如果不单独调用field方法,dataclass装饰器就对被dataclass装饰的对象中的每个成员变量(按照上述函数原型中的默认值)执行操作
因为上面的默认值中init=True,所以默认情况下,被dataclass装饰的对象中的所有成员变量会执行init操作。
因为上面的默认值中default=MISSING,所以默认情况下,被dataclass装饰的对象中的所有成员变量没有默认值。
因为上面的默认值中default_factory=MISSING,所以默认情况下,被dataclass装饰的对象中的所有成员变量没有默认的工厂函数。
如果想要控制被dataclass装饰的对象中的每个成员变量的具体执行动作,可以在成员变量构造的时候,设置单独的field方法
比如不想初始化某一个成员变量,就可以将field方法设置为init=False。 这就是上面的3.1.2. 章节的内容
也可以通过field方法设置某一个成员变量的默认值,但是这样有点大材小用了。

特殊的__post_init__方法

类在初始化的时候传入了两个值(或者多个值),但是根据这两个值会自动可以确认第三个值,我不希望再单独调用后生成第三个值。
即: 我期望在我给初始化传入两个值后,完成初始化动作后,第三个值自动生成了。
from dataclasses import dataclass, field
@dataclass
class C:
  a: float
  b: float
  c: float = field(init=False)
  
  def __post_init__(self):
    self.c = self.a + self.b

c1 = C(10,20)
print(c1) # c1:C(a=10, b=20, c=30)

标签:__,初始化,field,init,dataclass,默认值,装饰
From: https://www.cnblogs.com/weiweivip666/p/16667137.html

相关文章

  • 11.6面向对象的3个装饰器
    #比如计算学生得年龄,传生日#importtime##classStudent:##def__init__(self,name,birth):#self.birth=birth#self.name=name##@pro......
  • Python 装饰器
    Python装饰器假设我们想为已经编写的代码添加额外的功能,例如我们想在一个特殊的trycatch块中捕获任何错误,我们可以按如下方式进行。defsome_decorator(func):d......
  • go 闭包和装饰器
    闭包go中实现闭包需要依赖匿名函数packagemainimport("fmt")funcfoo(namestring)func(){returnfunc(){fmt.Println("hello",name)......
  • 普通函数、参数、匿名函数、高阶函数、递归函数、闭包、装饰器
    函数定义#定义函数deffn():print("这是函数内部")#调用fn()fn()#区分fn:这是真正意义上的函数本身fn():这是调用函数参数形参实参函数参数可有......
  • 设计模式之(7)——装饰设计模式
    定义:装饰设计模式允许向一个现有的对象添加功能,而不改变其结构(这就很符合程序设计的“开闭原则”),重点突出类功能的增强,属于结构型创建模式,这种模式创建了一个装饰类,用......
  • Flask 学习-32.flask_jwt_extended 自定义装饰器
    前言创建自己的装饰器来扩展此扩展提供的装饰器的功能。例如,您可能想要创建自己的装饰器来验证JWT是否存在以及验证当前用户是否是管理员。自定义装饰器flask_jwt_ext......
  • C# 装饰模式
    //Seehttps://aka.ms/new-console-templateformoreinformation/**个人理解你要往原有的东西上加东西Phone=装饰手机原材料Decorator=装饰手机中间人Xiao......
  • python基础-装饰器
    python基础-装饰器 什么是装饰器?不改变函数原来的调用方式动态地给函数添加功能 装饰器的原则是什么?装饰器遵循:开放封闭原则对添加新功能是......
  • 设计模式-装饰者模式(Decorate)
    首先我们来看一下装饰者模式的UML图 图中各个类的含义不懂没有关系,下面我会用一个形象的例子来一一介绍他们,相信大家看完后肯定就明白了  比如,我们玩了一款游戏,里......
  • python基础__装饰器(修饰器)
    装饰器处理逻辑当解释器读到@装饰符,会先解析@下一行的内容,把下一行的函数或者类作为@后边的函数的参数,执行被装饰的函数。例子1:被修饰函数不带参数1deflog(func):......