构造方法伪造成属性及修改属性值

偶尔善良 提交于 2020-02-03 18:48:12

构造方法伪造成属性、修改和删除属性值

在类的构造中,如果所要求得的结果是名词,但是结果的求值必须通过类的构造方法才能实现,那么可以通过在方法上添加装饰器把方法伪造成类的属性进行打印,这样就符合了名词的要求。

  • 把方法伪造成类的属性: @property伪造的属性名是构造方法的方法名,属性值是构造方法的返回值,使用@property后调用不需要加括号。

    Note

    注意:凡是类似于bmi这种需要计算并且名字又是名词属性的,都需要在构造方法上添加@property装饰器

    '''
    计算bmi值,第一种方式:把bmi的作为构造方法,可以实现基本bmi求值
    '''
    class Person(object):
      def __init__(self, name, age, weight, hight):
          self.name = name
          self.age = age
          self.__weight = weight
          self.__hight = hight
    
      def bmi(self):
          return '%s的bmi值为%s' % (self.name, self.__weight / self.__hight ** 2)
    
    p1 = Person('李镇', 18, 120, 1.77)
    print(p1.bmi())
    # 这中方式虽然可以实现求值,语法也没有问题,但是bmi是名词,方法确是动词,不是很合适
    
    '''
    第二种方式:在bmi构造方法上添加装饰器,把方法转换成为类的属性值
    '''
    class Person(object):
      def __init__(self, name, age, weight, hight):
          self.name = name
          self.age = age
          self.__weight = weight
          self.__hight = hight
    
      @property
      def bmi(self):
          return '%s的bmi值为%s' % (self.name, self.__weight / self.__hight ** 2)
      # 在方法上添加@property可以把方法名转换成类的属性
    
    p1 = Person('李镇', 18, 60, 1.77)
    print(p1.bmi)
    # 转换后直接用实例对象调用属性,不加括号。方法名为伪装后的属性名,方法的结果是属性的值
    # 把一个方法伪装成为一个属性,在代码级别上没有本质的提升,但是可以让代码看起来更加合理。
  • 伪造的属性不能直接修改属性值,如果需要修改必须用到@伪造属性名.setter来设定

    • 写构造函数:函数名是伪造成属性前的方法名,参数分别是:self和修改值
    • 在改方法上添加@伪造属性名.setter
    class Student(object):
      def __init__(self, name, age, gender):
          self.name = name
          if type(age) is int:
              self.__age = age
          else:
              print("请输入正确的数据类型")
          # 可以在__init__中判断属性是否符合要求
          self.gender = gender
    
      @property
      def age(self):
          return self.__age
    
      @age.setter
      # 伪装成属性的方法名.setter
      def age(self, a):
          self.__age = a if type(a) is int else print("请输入正确的数据类型")
    
    
          # 伪装前的方法,修改内容
          # self.__age = a
    
    s1 = Student('刘洋', 23, '女')
    print(s1.age)
    s1.age = 26
    print(s1.age)
    # 修改属性成功
  • 删除属性值

    • 需要用到@属性名.deleter

    • 创建执行删除操作的构造方法, del 属性进行删除

      class Student(object):
          def __init__(self, name, age, gender):
              self.name = name
              if type(age) is int:
                  self.__age = age
              else:
                  print("请输入正确的数据类型")
              # 可以在__init__中判断属性是否符合要求
              self.gender = gender
      
          @property
          def age(self):
              return self.__age
      
          @age.setter
          # 伪装成属性的方法名.setter
          def age(self, a):
              self.__age = a if type(a) is int else print("请输入正确的数据类型")   
              # 伪装前的方法,修改内容
              # self.__age = a
          @age.deleter
        # 删除的装饰器
          def age(self):
              del self.__age
              #这里需要在构造方法内执行del self.__age才能真正执行删除的操作
      s1 = Student('刘洋', 23, '女')
      print(s1.age)
      s1.age = 26
      print(s1.age)
      # 修改属性成功 
      del s1.age
      # del 对象.属性执行删除的命令
      
      '''
      结果是:
      23
      26
      Traceback (most recent call last):
        File "/Volumes/workspace/python-study/re_st/属性.py", line 80, in <module>
          print(s1.age)
        File "/Volumes/workspace/python-study/re_st/属性.py", line 59, in age
          return self.__age
      AttributeError: 'Student' object has no attribute '_Student__age'
      此时已经执行完删除的操作,所以再次执行打印的时候会进行报错
      '''

Note

  • 需要注意的是:伪造前的方法名、修改属性值的装饰器中.setter前的内容和修改属性值的构造方法名必须保持一致
  • 在__init__和其他的构造方法中可以通过if条件来判断属性值是否符合要求,但是不能用return来返回,可以用print或者赋值操作
  • 装饰器@property和@伪造属性名.setter是相对应的,前者用于伪造属性,后者用于修改属性值
标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!