版权声明:转载 或者复制请标注来源 https://blog.csdn.net/qq_34979346/article/details/83758447
我先问大家个问题。
如何对属性进行校验呢 比如有个要保证 age 属性 它只能是int类型且大小处于0到100之间?
第一直觉就是用get 和set 方法如下:
1.基本的调用 set 和get 方法
class Student:
def __init__(self):
pass
def get(self):
return self.age
def set(self,age):
if isinstance(age,int) and 0<age<100:
self.age=age
else:
print("请输入合法的年龄")
stu=Student()
stu.set(110) #请输入合法的年龄
stu.set(10)
print(stu.get()) #10
有的小伙伴该说了,你这太低级了,现在都是用property 了
2.利用@property
对,正确的做法就是 用**@property 装饰器**,可以把方法封装成
属性。
例如:
class Student:
def __init__(self):
pass
@property
def age(self):
return self.value
@age.setter
def age(self,value):
if isinstance(value,int) and 0<value<100:
self.value=value
else:
print("请输入合法的年龄")
stu=Student()
stu.age=10
print(stu.age) # 10
恭喜你明白了@property 的用法。前面都是引子,现在开始我们的正题。
现在又有一个场景:
像age属性 一共有十几个,你该如何做呢
用@property 是可以做到,你知道你需要写多少方法吗,得写20多个,
这代码量也实在太大了吧,这个难道不了我们的优秀的高级开发测试员。
3.利用属性描述符
属性描述符的原理利用的是抽象的方法, 把十几个字段共同的特性抽出来,
每个字段都用这个特性,达到节省代码的目的。 看下 下边的例子:
class Int_validation:
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
if isinstance(value,int) and 0<value<100:
self.value=value #这个要注意 要用value,不能用instance 否则会陷入死循环
else:
print("请输入合法的数字")
def __delete__(self, instance):
pass
class Student:
age=Int_validation()
stu=Student()
stu.age=50
print(stu.age)
解释下
- 首先我们要把共同的校验封装在一个类里也就是 Int_validation 类,
- 重写两个魔法函数 (get 和set)
- age=Int_validation() 这个是关键,age 本来是个对象,放在类里当作了Student类属性
- 实例化对象stu给age进行赋值 ,它会自动调用Int_validation get的方法 ,我们debug get方法看下过程
value = {int} 50
self = {Int_validation} <__main__.Int_validation object at 0x0000025AA8362CC0>
instance = {Student} <__main__.Student object at 0x0000025AA8362CF8>
显然会把 50 给value, self 就是age本身, instance就是stu
这就是为什么不能 self.instance=instance,而是 self.value=value ,
它会再走一次流程进入死循环。
value=50 进入校验流程 。
5. 当我们调用了 stu.age ,它会调用get方法 并返回值。
debug 的代码
instance = {Student} <__main__.Student object at 0x000001883B6F2CF8>
self = {Int_validation} <__main__.Int_validation object at 0x000001883B6F2CC0>
总结:
1.其他属性也可以用age 方式,自己可以试试
2.这里面 有属性描述符的三要素 要掌握并理解它们的含义, (value,instance,self)缺一不可。
3.巧妙的利用了三个魔法函数,正好 校验类对象是应用类的属性,并且你们会发现我们并没有
调用set和get 方法,这也是魔法函数的特性 。
有不明白的或者错误的请联系我,或者在下边评论 ,谢谢