装饰器property
1 class Student(): 2 def __init__(self,score): 3 self.score = score 4 5 s1 = Student(59) # 实例化对象并给对象属性赋值 6 s1.score = 80 # 这样直接就能过 实例.数据属性来修改市里的属性值,会导致用户由于不了解业务逻辑随意修改了属性值 7 print(s1.score) # 结果:80 8 s2 = Student(110) 9 print(s2.score) # 结果发现数据属性score能够赋值超过100,这个不合理
# 存在问题:
# 1.实例可以直接修改数据属性
# 2.实例的属性设置不合理
########## 分割 ###############
1 class Student(): 2 def __init__(self, score): 3 self.__score = score # 通过__符号来标识此属性为类的私有属性,解决了实例直接修改属性的问题,但是没办法获取到数据属性 4 5 6 s1 = s2 = Student(59) # 实例化对象并给对象属性赋值 7 print(Student.__score) # 无论是类还是实例均无法类的外部(类的内部是可以操作的)直接获取到类的私有属性 8 print(s1.__score) # 同上 9 s2.__score = 80 # 既然无法获取,当然也无法直接复制
########## 分割 #################
1 class Student(): 2 def __init__(self, score): 3 self.__score = score # 通过__符号来标识此属性为类的私有属性,解决了实例直接修改属性的问题,但是没办法获取到私有数据属性 4 5 # 增加设置属性的方法来修改数据属性值 6 def set_score(self,s): 7 self.__score = s # 类的内部是可以调用类的私有属性的 8 9 # 增加获取方法来获取数据属性值 10 def get_socre(self): 11 return self.__score 12 13 s1 = s2 = Student(59) # 实例化对象并给对象属性赋值 14 print(s1.get_socre()) # 结果:59 15 print(s2.get_socre()) # 结果:59 16 s1.set_score('89') # 调用类方法操作私有属性,更改了类的私有属性 17 print(s1.get_socre()) # 结果:89 18 print(s2.get_socre()) # 结果:89
# 好处:
# 1.解决了实例随意更改数据属性的问题
# 2.但是仍然没有限制非法值的问题
########## 分割 #################
1 class Student(): 2 def __init__(self, score): 3 self.__score = score # 通过__符号来标识此属性为类的私有属性,解决了实例直接修改属性的问题,但是没办法获取到私有数据属性 4 5 # 增加设置属性的方法来修改数据属性值 6 def set_score(self, s): 7 if int(s) <= 100 and int(s) >= 0: # 增加非法值校验 8 self.__score = s # 类的内部是可以调用类的私有属性的 9 else: 10 raise ValueError('score should between 1 ~ 100 !') 11 12 # 增加获取方法来获取数据属性值 13 def get_socre(self): 14 return self.__score 15 16 17 s1 = s2 = Student(59) # 实例化对象并给对象属性赋值 18 print(s1.get_socre()) # 结果:59 19 print(s2.get_socre()) # 结果:59 20 # s1.set_score('110') # 此处会抛出异常,因为不允许值大于100 21 s2.set_score(78) 22 print(s1.get_socre()) # 结果:78 23 print(s2.get_socre()) # 结果:78
# 好处:
# 1.解决了实例随意更改数据属性的问题
# 2.解决了传入非法值的问题(增加了非法值的校验)
# 存在问题:
# 1.想要更改数据属性,结果调用看起来是以调用的方法的方式调用
########## 分割 #################
1 class Student(): 2 def __init__(self, score): 3 self.__score = score # 通过__符号来标识此属性为类的私有属性,解决了实例直接修改属性的问题,但是没办法获取到私有数据属性 4 5 # 增加获取方法来获取数据属性值 6 @property 7 def get_socre(self): 8 return self.__score 9 10 # 增加设置属性的方法来修改数据属性值 11 def set_score(self, s): 12 if int(s) <= 100 and int(s) >= 0: # 增加非法值校验 13 self.__score = s # 类的内部是可以调用类的私有属性的 14 else: 15 raise ValueError('score should between 1 ~ 100 !') 16 17 s1 = s2 = Student(59) # 实例化对象并给对象属性赋值 18 print(s1.get_socre) # 结果:59,已经是类似于数据属性的调用方法了 19 print(s2.get_socre) # 结果:同上 20 # s1.set_score('110') # 此处会抛出异常,因为不允许值大于100 21 s2.set_score(78) 22 print(s1.get_socre) # 结果:78 23 print(s2.get_socre) # 结果:78
# 好处:
# 1.解决了实例随意更改数据属性的问题
# 2.解决了传入非法值的问题(增加了非法值的校验)
# 3.解决了获取数据属性调用是以调用数据属性的方式调用
# 存在问题:
# 设置和获取需要单独来写,看起来不直观
########## 分割 #################
1 class Student(): 2 def __init__(self, score): 3 self.__score = score # 通过__符号来标识此属性为类的私有属性,解决了实例直接修改属性的问题,但是没办法获取到私有数据属性 4 5 # 增加获取方法来获取数据属性值 6 @property 7 def score(self): # 获取属性方法 8 return self.__score 9 10 # 增加设置属性的方法来修改数据属性值 11 @score.setter # 这里是获取方法的setter方法 12 def score(self, s): # 设置属性方法 13 if int(s) <= 100 and int(s) >= 0: # 增加非法值校验 14 self.__score = s # 类的内部是可以调用类的私有属性的 15 else: 16 raise ValueError('score should between 1 ~ 100 !') 17 18 s1 = s2 = Student(59) # 实例化对象并给对象属性赋值 19 print(s1.score) # 结果:59,已经是类似于数据属性的调用方法了 20 print(s2.score) # 结果:同上 21 # s1.score('110') # 此处会抛出异常,因为不允许值大于100 22 s2.score = 67 23 print(s1.score) # 结果:78 24 print(s2.score) # 结果:78
# 好处:
# 1.解决了实例随意更改数据属性的问题——必须通过调用类方法的方式来设置私有数据属性值
# 2.解决了传入非法值的问题——增加了非法值的校验
# 3.解决了获取数据属性调用方式——看起来是以调用数据属性的方式调用
# 4.解决了设置和获取需要单独来写的问题——设置,类似于属性赋值;获取类似于属性调用
############ 重点来了 ####################
为啥实例1的属性改了实例2的属性也跟着改呢,能不能避免这种情况,下面上代码,也是常用的代码(s1 = s2 = Student()一开始没理解)
1 class Student(): 2 def __init__(self,s): 3 self.__score = s 4 5 @property 6 def score(self): 7 return self.__score 8 9 @score.setter 10 def score(self,s): 11 if int(s) <=100 and int(s) >=0: 12 self.__score = s 13 else: 14 raise ValueError('value not legal !') 15 16 s1 = Student(59) 17 s2 = Student(63) 18 s1.score = 89 19 print(s1.score) # 结果:89 20 print(s2.score) # 结果:63
# 类方法——待补充
# 静态方法——待补充