python dataclass_[Python] 3.7中的dataclasses

本文详细介绍了Python 3.7中新增的数据类`dataclass`,如何减少定义数据类的代码量,并通过实例展示了`dataclass`的`init`, `repr`, `eq`, `order`, `unsafe_hash`, `frozen`等参数的作用,以及如何使用`field()`方法为字段附加额外信息。同时,文中还讨论了`frozen`属性对实例修改的影响,以及`default_factory`参数如何为字段设置默认值。" 9935437,1456717,Android SD卡XML文件扫描实现,"['Android开发', '文件操作', 'XML处理']
摘要由CSDN通过智能技术生成

简介:

这个dataclasses是当做装饰器来用,作用是在我们定义数据class对象时减少我们的代码量。

文章主要是用IDE写的,还请见谅。

?

正文:

from dataclasses import dataclass

#带上这个装饰器帽子,相当于它的init,repr,eq等双下划线方法都自动帮我们创建

@dataclass(init=True, repr=True, eq=True, order=True,unsafe_hash=False, frozen=False)

class Point:

x: float

__y: float #外部不可访问和更改

z: float = 0.0

# def __repr__(self): #你也可以自己重写魔术方法,它将是最终生效的那个

# return "test"

p = Point(1.1,2.2) #加了装饰器可以直接进行赋值使用

p.__y = 111 #无法修改

print(p) #Point(x=1.1, _Point__y=2.2, z=0.0)

'''

戴帽子的时候也可以这样写:

@dataclass(init=True, repr=True, eq=True, order=False, unsafe_hash=False, frozen=False)

是的,你可以决定哪些魔术方法需要装饰器帮你自动添加到class中,注意它们的默认值。

init,repr这两个就不说了,__eq__这个方法:

它将class当做一个填充有字段的元组来比较是否相等,而且要求字段名,值,顺序,类型全部一致才算相等。

'''

p1 = Point(1.1,2.2)

p2 = Point(z=2.2,x=1.1,_Point__y=0) #改变了形参位置

print(p==p1, p==p2) #true false

'''

order=True的话,那么__lt__,__le__,__gt__,ge__也就是,>=这些魔术方法都会生成到你的class中

#如果False,则定义的class不支持比较,会抛异常,除了==

默认的比较规则貌似是只比较第一个参数,你最好自己重写这些方法

'''

@dataclass(order=True)

class Point_1:

x: float

y: int

p3=Point_1(0.0, 1)

p4=Point_1(0.1, 0)

print(p3

'''

frozen=True的话,class的实例不支持修改,即instance.field=xxx 都是不支持的

'''

@dataclass(frozen=True)

class Point_2:

x: float

y: int

z: dict

# def __setattr__(self, key, value): #若frozen=true,连这个setattr方法都不允许定义(getattr也不准,参照https://www.python.org/dev/peps/pep-0557/#specification)

# self.z[key] = value

def __getattr__(self, item): #不过这里并没有抛出异常

return self.item

# def __delattr__(self, item): #同样,它也不给定义

# del self.y

p3=Point_2(0.0, 1, {})

# p3.y = 1 #dataclasses.FrozenInstanceError: cannot assign to field 'y'

print(p3.z) #居然是可以访问的

'''

frozen: If true (the default is False), assigning to fields will generate an exception.

This emulates read-only frozen instances. If either __getattr__ or __setattr__ is defined in the class, then ValueError is raised

原话说的是模仿一个 只读的实例,__getattr__和__setattr__都不允许自定义,否则抛异常。

个人认为__setattr__不允许自定义是ok的,__getattr__不允许那还怎么读呢,所以这里应该是表述有问题。

'''

'''

unsafe_hash默认是false,但它会根据eq和frozen参数来进行设置

若eq和frozen都是true,那么__hash__方法将会添加到class中

若eq=true,frozen=false,那么__hash__=None, 且标记class为unhashable的类

若eq=false,将保持原来的__hash__方法,意思是使用class父类的哈希方法,python3中默认类都是继承自object类(或者继承了别的类)。

'''

@dataclass(frozen=True)

class Point_3:

x: float

p4 = Point_3(1)

print(p4.__hash__) # 标明此类是有hash方法的

print(p4.__hash__()) # 3430019387558 调用其hash方法,等效于hash(p4)

print(hash(p4) == p4.__hash__())

@dataclass(frozen=False,eq=True) #这个时候__hash__=None

class Point_4:

x: float

p5 = Point_4(1)

print(p5.__hash__) #None

# print(p5.__hash__()) #'NoneType' object is not callable

'''

##关于field()方法##

有时候在数据类中我们需要给一些字段附加一些额外的信息,

如a这个字段我要定死,不给它走init,在repr中也不希望被显示出来,还不希望拿来比较

'''

from dataclasses import field

@dataclass(unsafe_hash=True) #强制生成__hash__方法

class Point_5:

x: float

y: int = field(default=10,init=False,repr=False)

z: str = field(default="", compare=False) #比较时忽略此字段

f: str = field(default="", hash=False) #true的话,hash后的结果是不一样的

p6 = Point_5(x=1, z="A") #不再允许被设置

print(p6.y) #10 仍然可以访问

print(p6) #Point_5(x=1) 显示的查看对象也看不到y的值了

p7 = Point_5(x=1, z="B")

print(p6==p7) #true z被忽略了,只比较了x

print(hash(p7))

#使用default_factory参数来为字段设置默认值,他必须是一个可调用的对象,比如func,class

#要注意它和default是不相容的,有你没我,定义时只能使用两者中一个参数

def generate_x():

return 1

@dataclass

class Point_6:

x: float = field(default_factory=generate_x) #

y: float = field(default_factory=dict) #list, str, int...

p8 = Point_6()

print(p8) #Point_6(x=1)

如上已经介绍了大部分dataclasses库的用法,更多关于它的使用参考

python3.7的更新参考

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值