Python是一种面向对象的语言。一般来说,使用面向对象编程会使开发效率更高,软件质量更好,代码更容易扩展,可读性和可维护性更高。但是Python的类写起来真的很累,所以创建类的时候可以自动添加attrs模块。我们会在下面的文章中介绍这个东西,有需要的朋友可以参考一下。
目录
1,使用属性2,验证器3,转换器前言:
Python是一种面向对象的语言。一般来说,使用面向对象编程会导致更高的开发效率、更好的软件质量、更容易的代码扩展、更高的可读性和可维护性。但在更大的项目中,如果有很多属性非常复杂的实体类,你会逐渐觉得Python的类写起来真的很“累”。为什么这么说?看看下面的盒子类。它的属性是长度、宽度和高度:
类别框:
def __init__(自身,长度,宽度,高度):
自身长度=长度
自身宽度=宽度
self.hight=hight
这个没毛病,而且是按照Python规范写的。初始化函数中的每个参数都需要赋值self.xxx=xxx。参数少是好的,但是参数太多的话,光是参数赋值操作就够写一段时间了。如果一个项目里有很多类,那就真的麻木了。
而且我们知道,在Python中,当你想自定义对象本身的打印输出时,需要在它的类例如:中实现__repr__()方法。
def __repr__(self):
返回“{}(长度={},宽度={},高度={})”。格式(
自我。__class__。__name__,自身长度,自身宽度,自身高度)
实现了__repr__()方法,当我们打印对象本身时,我们将输出我们的自定义字符。
box=Box(20,15,15)
打印(方框)
#结果输出是box(长=20,宽=15,高=15)
但是有时候因为麻烦,我们不想实现__repr__()方法,但是因为没有意识到打印出来的结果,不友好,就卡住了。
如果要比较对象,有时需要判断两个对象是否相等或者比较大小,所以要实现__eq__()、__lt__()、__gt__()等各种方法来比较对象,例如: 。
def __eq__(自己,其他):
如果不是isinstance(other,self。__class__):
返回未实现
return (self.length,self.width,self . height)=(
其他长度、其他宽度、其他高度)
这样,我们就需要实现这些方法来进行比较。举个例子,如果我们已经实现了上面提到的所有方法,然后突然增加了一个属性firmness hardness,那么整个类的方法都需要修改,非常折磨人。那么有没有办法在创建类的时候自动添加类似上面提到的东西呢?答案是肯定的,就是我们接下来要介绍的attrs模块,可以帮助我们方便的定义类。
1、attrs的使用
我们可以使用pip安装属性进行安装。
然后将上面的代码改造一下:
从属性导入属性,属性
@attrs
类别框:
length=attrib(type=int,默认值=0)
width=attrib(type=int,默认值=0)
hight=attrib(type=int,默认值=0)
box1=Box(20,15,15)
打印(方框1)
box2=Box(30,20,20)
打印(box2==box1)
打印(方框2方框1)
在模块中用attrs修饰Box类,然后用attrib定义所有属性,指定属性的类型和默认值。我们没有实现上面提到的任何方法,但是我们实现了所有的功能。现在如果我们加一个属性颜色,不参与对象的比较,但打印时需要输出,再加一个属性硬度,参与对象的比较,但打印对象时不输出,就很简单了:
从属性导入属性,属性
@attrs
类别框:
length=attrib(type=int,默认值=0)
width=attrib(type=int,默认值=0)
hight=attrib(type=int,默认值=0)
color=attrib(repr=True,cmp=False,default=(0,0,0))
硬度=属性(repr=假,cmp=真,默认值=0)
box1=Box(20,15,15,(255,255,255),80)
打印('方框1:',方框1)
box2=Box(20,15,15,(255,255,0),100)
打印('方框2:',方框2)
打印(box2==box1)
打印(方框2方框1)
执行结果为:
也就是说,如果我们使用attrs库,它会让类的定义变得高效简洁,不需要编写冗余复杂的代码。在属性()上,接收以下参数:
默认值:属性的默认值。如果没有传入初始化数据,将使用默认值。
Validator: Validator,检查传递的参数是否合法。
Repr:是否参与对象打印的输出。
Cmp:是否参与对象比较?
哈希:是否进行重复数据删除?
Init:是否参与初始化。如果为False,则此参数不能用作类的初始化参数。默认值为True。
元数据:元数据,只读附加数据。
Type:类型,如int、str等。默认值为无。
Converter:转换器,处理并转换一些值,以增加容错能力。
Kw_only:是否为强制关键字参数;默认值为False。
这里我们只关注验证器和转换器,其他参数都很好理解。
2、验证器
有时候设置属性必须满足一定的条件,比如上面的颜色属性。我们用RGB三原色,比如黑色是(255,255,255)。在这种情况下,我们需要验证属性是否合法。
例如:
定义颜色有效(实例,属性,值):
如果不是isinstance(值,设置):
Raise ValueError(f '参数{attr.name}:{value}是非法的!')
对于i in值:
如果不是0=i=255:
Raise ValueError(f '参数{attr.name}:{value}是非法的!')
@attrs
类别框:
length=attrib(type=int,默认值=0)
width=attrib(type=int,默认值=0)
hight=attrib(type=int,默认值=0)
color=attrib(repr=True,cmp=False,validator=color_is_valid,default=(0,0,0))
硬度=属性(repr=假,cmp=真,默认值=0)
box1=Box(20,15,15,(255,255,260),80)
执行结果是:
上面的代码中定义了一个verifier color_is_valid()方法来验证颜色color是否合法,如果不合法就会抛出异常。
验证器方法接收三个参数:
实例:类对象
属性:属性名
值:属性值
而且attrs模块还提供了很多内置的验证器,这里就不赘述了。
3、转换器
转换器主要处理和转换一些值,增加类的容错性。例如,如果一个属性接收一个int类型,我们想要的是当一个数字字符串被传入时不会有错误。然后我们可以添加一个转换器,自动将字符串转换为数字,例如:。
def to_int(值):
尝试:
返回int(值)
除了:
不返回
@attrs
类别框:
length=attrib(type=int,默认值=0,converter=to_int)
width=attrib(type=int,default=0,converter=to_int)
hight=attrib(type=int,默认值=0)
color=attrib(repr=True,cmp=False,default=(0,0,0))
硬度=属性(repr=假,cmp=真,默认值=0)
box1=Box('20 ',' 15 ',15,(255,255,255),80)
打印('方框1:',方框1)
box2=Box('2a ',15,15,(255,255,0),100)
打印('方框2:',方框2)
上面定义了一个方法to_int(),可以把一个值转换成数值类型,转换异常会返回None,所以容错性很高。
这是这篇关于Python attrs提高面向对象编程效率的详细文章的结尾。有关Python attrs提高面向对象编程效率的更多信息,请搜索我们以前的文章或继续浏览下面的相关文章。希望大家以后能多多支持我们!
郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。