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.\n' '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