python_@propetry

@propetry的作用就是让一个方法可以当成属性被调用。

@property的实现比较复杂,我们先考察如何使用。把一个getter方法变成属性,只需要加上@property就可以了,此时,@property本身又创建了另一个装饰器@score.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作

class Rectangle():
    
    @property
    def width(self):
        return self._width

    @width.setter
    def width(self, value):
        if not isinstance(value,int):
            raise ValueError('be int!')
        if value < 0 or value > 100:
            raise ValueError('valueError')
        self._width = value

    @property
    def squer(self):
        return self._width * self._width

s = Rectangle()
s.width = 20    #width这个属性是可读可写的,写入时还会检查
print(s.squer)  #squer这个属性时只读的,无法写入,会报错。

  

一个例子:

    # 使用@property装饰器,data会被self.data这个属性调用,返回_data
    # 这样可以对参数进行检查
    @property
    def data(self):
        # is_valid会把initial_data替换为_validated_data
        # 这个if防止没有调用is_valid
        if hasattr(self, 'initial_data') and not hasattr(self, '_validated_data'):
            msg = (
                'When a serializer is passed a `data` keyword argument you '
                'must call `.is_valid()` before attempting to access the '
                'serialized `.data` representation.
'
                'You should either call `.is_valid()` first, '
                'or access `.initial_data` instead.'
            )
            raise AssertionError(msg)

        # 设定返回值_data
        if not hasattr(self, '_data'):
            if self.instance is not None and not getattr(self, '_errors', None):
                self._data = self.to_representation(self.instance)
            elif hasattr(self, '_validated_data') and not getattr(self, '_errors', None):
                self._data = self.to_representation(self.validated_data)
            else:
                self._data = self.get_initial()
        return self._data

    # 参数检查:没有_errors,则self.errors调用就会出错
    @property
    def errors(self):
        if not hasattr(self, '_errors'):
            msg = 'You must call `.is_valid()` before accessing `.errors`.'
            raise AssertionError(msg)
        return self._errors

    # 参数检查:没有_validated_data,则self.validated_data调用就会出错
    @property
    def validated_data(self):
        if not hasattr(self, '_validated_data'):
            msg = 'You must call `.is_valid()` before accessing `.validated_data`.'
            raise AssertionError(msg)
        return self._validated_data