修饰符
修饰符可以看作是属性的访问中介,修饰符对象通常在类定义时被创建。修饰符是为属性服务的。
修饰符模式有两部分: 拥有者类(owner class) 和 属性修饰符(attribute descriptor)。
特性是基于 拥有者类的,而修饰符与拥有者类之间没有固定的关系,所以是可以重用的。
对拥有者类存在的属性进行一些修饰。可以进行类型检查,关联更新
非数据修饰符
需要定义 set 或者 delete方法,或者两个都定义
class UnitValue:
def __init__(self, unit):
self.value = None
self.unit = unit
self.default_format = '5.2f' # 格式化的参数,意思是最小占5个位置,保留两位小数
# set函数是用来赋值的
def __set__(self, instance, value):
self.value = value
# str是实例对象的的文字返回值
def __str__(self):
return "{value:{spec}} {unit}".format(spec=self.default_format,**self.__dict__)
# format是在调用 format函数时执行的函数。 instance.__format__('10.2f')与format(instance,'10.2f')的意思时相同的
def __format__(self, spec='5.2f'):
if spec == '': spec = self.default_format
return "{value:{spec}} {unit}".format(spec=spec, **self.__dict__)
class RTD:
# 实例化修饰对象。函数中调用这样的类属性使用self.rate调用
rate = UnitValue('kt') #速度
time = UnitValue('hr') #时间
distance = UnitValue('nm') #距离
def __init__(self, rate=None, time=None, distance=None):
if rate is None:
# 对修饰符对象赋值,即对修饰对象中的value赋值
self.time = time
self.distance = distance
self.rate = distance / time
if time is None:
self.distance = distance
self.rate = rate
self.time = distance / rate
if distance is None:
self.rate = rate
self.time = time
self.distance = rate * time
def __str__(self):
# self为传入的第一个参数,所以0.rate = self.rate
# 这里的调用顺序是,先调用修饰对象中的str方法,返回一个字符串对象,然后在执行当前的格式化
return 'rate: {0.rate} time: {0.time} distance: {0.distance}'.format(self)
>> r = RTD(rate=6, distance=20)
>> print(r.rate)
>> 6.00 kt
>> print(r)
>> rate: 6.00 kt time: 3.33 hr distance: 20.00 nm
数据修饰符
class Unit:
conversion = 1.0
def __get__(self, instance, owner):
return instance.kph * self.conversion
def __set__(self, instance, value):
instance.kph = value / self.conversion
class Knots(Unit):
# 海里
conversion = 0.5399568
class MPH(Unit):
# 英里
conversion = 0.62137119
class KPH(Unit):
def __get__(self, instance, owner):
return instance._kph
def __set__(self, instance, value):
instance._kph = value
class Measurement:
kph = KPH()
knots = Knots()
mph = MPH()
def __init__(self,kph=None,mph=None,knots=None):
if kph: self.kph = kph
elif mph: self.mph = mph
elif knots: self.knots =knots
else:
raise TypeError
# print(self.__dir__()) #kph等是类属性,需要用dir查看
# print(self.__dict__) # dict中没有
def __str__(self):
return "rate: {0.kph} kph = {0.mph} mph = {0.knots} knots".format(self)
>> m = Measurement(mph=5.9)
>> print(m)
>> rate: 9.495129634188544 kph = 5.8999999999999995 mph = 5.1269598128616165 knots