python基础第十五课--OOP创建可管理的属性(property)(小白piao分享)
为类创建可管理的属性
概述:我们可以在实例属性的获取和设定上增加一些额外的功能,比如在设定时增加类型的检查
解决方案:
要自定义对属性的访问,一种简单的方式是将其定义为property,增加了对属性的类型检查:
class Person:
def __init__(self,first_name):
self.first_name = first_name
#getter
@property
def first_name(self):
return self._first_name
@first_name.setter
def first_name(self,value):
if not isinstance(value,str):
raise TypeError('Expected a string')
self._first_name = value
@first_name.deleter
def first_name(self):
raise AttributeError('Can`t delete attribute')
上述代码中一共有三个相互关联的方法,三个方法必须名字相同,第一个是getter函数,将first_name设置为了property,并且附带绑定了两个可选方法setter和deleter方法,值的注意的是,如果没有设置property,是不能设置setter 和 deleter装饰器的 。
property的本质就是是的修饰内容更像是一个属性(而非方法),通过对属性进行赋值和del处理会自动调用装饰器setter和deleter对应装饰的方法,实例如下:
#对上述例子进行操作:
pr = Person('小白piao')#调用setter
pr.first_name = '小白piao最sao'#调用setter
print(pr.first_name)#小白piao最sao #调用getter
del pr.first_name # AttributeError:Can`t delete attribute
#如果上述例子中对pr.first_name = 250;会抛出TypeError:Expected a string
#由此,便实现了对属性类型的限定
疑问:在__init__中为何是self.first_name = first_name,而不是self._first_name = first_name?
原因:其实由于下方设置了装饰器,所以在构造时,构造中的赋值实际上也是调用了setter方法,定义类在前,所以后边可以直接在创建对象是调用setter,这没有问题;这么做的目的,是为了在所有地方的属性设置时,都可以进行类型检查。如果在构造函数中使用‘self._first_name = first_name’,那么此处便不会调用setter,自然不会进行类型检查,所以这样会造成判断类型的疏忽,并不是说没有其他方法完成类型的检测。这样做在一定程度了规避了代码的大量重复。
同样也可以对已经存在的get和set、delete定义为property。
讨论:实际上,property的作用是将一系列的方法进行绑定,实际上可以通过调用property属性中的fget,fset,fdel方法来完成上述操作,但实际上并不会专门去调这些方法,而是通过特殊的操作诸如赋值、打印、删除都会自动调用以上三种方法。
其实有一点很重要,只有在确实需要在访问属性时完成一些额外的工作时,才会去想到使用property。因为:一、这样写语法会对其他程序员产生困扰,代码可读性不高;二、代码的运行会变慢,实际上每个装饰器都需要额外调用函数来完成装饰动作。三、不会给设计带来真正的好处。特别是以后决定对某个属性增加额外的处理步骤是,可以再不修改已有代码的情况下将这个属性提升为一个Property。
property可以用来定义需要被计算的属性:
import math
class Circle:
def __init__(self,radius):
self.radius = radius
@property
def area(self):
return math.pi * radius ** 2
@property
def perimeter(self):
return 2 * math.pi * radius
circle = Circle(2)
print(circle.area)
print(circle.perimeter)
property属性为我们提供了很多的使用的API,但是实际上,合理地使用它才是根本。不要一个类中都是property那会导致你的代码过度膨胀和丑陋,以至于不愿意读你写的代码,原因很简单,菜鸡看不明白。
上一篇: Day4 Python基础学习
下一篇: Java学习笔记 day4