装饰器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,这个不合理
View Code

 


# 存在问题:
# 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  # 既然无法获取,当然也无法直接复制
View Code

 



########## 分割 #################
 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
View Code

 



# 好处:
# 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
View Code

 



# 好处:
# 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
View Code

 



# 好处:
# 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
View Code

 



# 好处:
# 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

 



# 类方法——待补充
# 静态方法——待补充
posted @ 2019-08-27 14:02  唐大侠的小迷弟  阅读(160)  评论(0编辑  收藏  举报