zoukankan      html  css  js  c++  java
  • 装饰器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


    # 类方法——待补充
    # 静态方法——待补充
  • 相关阅读:
    一个小案例精通lamda表达式
    你想被开除吗?来看看程序员【离职小技巧】吧
    让 Flutter 在鸿蒙系统上跑起来
    “TensorFlow 开发者出道计划”全攻略,玩转社区看这里!
    环形单链表的增删改查、约瑟夫环两种解法
    一万字详解 Redis Cluster Gossip 协议
    Lambda表达式
    Linux系统中如何进入退出vim编辑器,方法及区别
    成为博客主的第一天
    【秋招内推】近期互联网公司秋招内推合集
  • 原文地址:https://www.cnblogs.com/wjlv/p/11417965.html
Copyright © 2011-2022 走看看