property属性
property实际是setter getter deleter是集合体,并不是一个单独的方法
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| import math class Circle: def __init__(self,radius): self.radius = radius @property # area = property(area) # def area(self): return math.pi * self.radius**2 @property def peirimeter(self): return 2*math.pi*self.radius c1= Circle(5) print(c1.radius) print(c1.area) print(c1.peirimeter)
|
结果:
5
78.53981633974483
31.41592653589793
注意:
c.area是不能赋值的,虽然我们能够当做看似通过属性进行调用,实际是不是的
结果是:
AttributeError: can’t set attribute
会抛出错误
下面是一个测试:
print(type(Circle.area)) #此时类是不能使用area函数的,结果是class property
print(Circle.area) # 结果是property object at 0x00000000006AB5E8
为什么要用property
将一个函数的类定义成property特性后,对象使用object.name,无法知道这个name是函数计算出来的,这种特性的使用方式遵循统一访问原则
面向对象中有三种类:
public –就是公开类
protected – 父类
private – 私有类
但是python的class机制并没有把这三种语法,像C++提供的是set和get方法,Python中是通过property方法提供
1 2 3 4 5 6 7 8 9 10 11 12
| class People: def __init__(self,name,SEX): self.name = name self.__sex = SEX @property def sex(self): return self.__sex p1 = People('aaa','male') print(p1.name) print(p1.sex)
|
结果:
male
aaa
通过属性的的方式是通过property的方式能够object.name的方式,这里就是用来实例化的p1.name p1.sex来是实现
但是这种属性并不是真正的属性,不能通过赋值的方式修改,后期需要进行修改用到了setter方法
setter方法是用了被property装饰器后的函数名命名了一个新的装饰器
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18
| class People: def __init__(self,name,SEX): self.name = name self.__sex = SEX @property def sex(self): return self.__sex @sex.setter # 想要对上面得函数属性进行修改 def sex(self,value): print(self,value) self.__sex = value p1 = People('aaa','male') p1.sex = 'femele' print(p1.sex)
|
结果:
famele
上面的关键是@sex.setter重新命名了一个新的装饰器,装饰器的名字是sex,它的方法是setter。p1.sex = ‘femele’ 这这执行的时候首先从property下面的sex.__sex,这里存放的是真实的sex的值,所以的赋值只能在这里
通过抛出异常,限制输入的参数必须是字符串
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| class People: def __init__(self,name,SEX): self.name = name self.sex = SEX @property def sex(self): return self.__sex @sex.setter # 想要对上面得函数属性进行修改 def sex(self,value): print(self,value) if not isinstance(value,str): raise TypeError("male 必须是字符串类型") self.__sex = value p1 = People('aaa','male') p1.sex = 'femele' print(p1.sex)
|
上面的修改是在setter中在修改赋值之前增加了异常处理,如果输入的不是字符串,就会抛出异常,但是这个只是在实例化赋值(p1.sex = 123)时候用才会抛出异常,在类的初始化的时候直接就self.sex=SEX,p1 = People(‘aaa’,123) # 实例化最初的时候就会抛出异常
删除操作
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| class People: def __init__(self,name,SEX): self.name = name self.sex = SEX @property def sex(self): return self.__sex @sex.setter # 想要对上面得函数属性进行修改 def sex(self,value): print(self,value) if not isinstance(value,str): raise TypeError("male 必须是字符串类型") self.__sex = value @sex.deleter def sex(self): del self.__sex p1 = People('aaa','male') print(p1.sex) del p1.sex
|