我不知道你对__get__()和__set__()有多少理解。python中如果一个类实现了__get__、__set__、__delete__三个方法的任意一个方法就是描述器。也就是说class Celsius和class Fahrenheit都是描述器。
Temperature类中有两个属性分别是以上两个类的实例,所以在Temperature类的实例temp中一旦触发描述器方法就会去调用对应描述器内的对应函数。
我在你的程序的基础上添加了一些print语句,可以很好的观察如何调用描述器方法的。#!/usr/bin/python3
class Celsius:
def __init__(self,value=26.0):
self.value = float(value)
def __get__(self,instance,owner):
print('In Celsius.__get__()....',instance,owner.__name__)
return self.value
def __set__(self,instance,value):
print('In Celsius.__set__()....',instance,value)
self.value = float(value)
class Fahrenheit:
def __get__(self,instance,owner):
print('In Fahrenheit.__get__()....',instance,owner.__name__)
return instance.cel * 1.8 + 32 #因为instance是一个Temperature类的实例temp,这里会调用数据描述器Celsius的__get__方法
def __set__(self,instance,value):
print('In Fahrenheit.__set__()....',instance,value)
instance.cel = (float(value)- 32) / 1.8
class Temperature:
cel = Celsius()#Temperature类属性放一个对象Celsius的实例赋值给cel
print(cel)
fah = Fahrenheit()#Temperature类属性放一个对象Fahrenheit的实例赋值给fah
print(fah)
print('frist sentence')
temp = Temperature()
print('second sentence')
temp.cel = 50# 修改描述器同名属性值,会调用数据描述器Celsius的__set__方法
print('thrid sentence')
print(temp.fah)# 实例调用类的属性描述器,调用数据描述器Fahrenheit的__get__方法
print('forth sentence')
print(temp.cel)# 实例调用类的属性描述器,调用数据描述器Celsius的__get__方法
运行结果:<__main__.Celsius object at 0x7f7f0ac2d0b8>
<__main__.Fahrenheit object at 0x7f7f0ac2d0f0>
frist sentence
second sentence
In Celsius.__set__().... <__main__.Temperature object at 0x7f7f0ac2d128> 50
thrid sentence
In Fahrenheit.__get__().... <__main__.Temperature object at 0x7f7f0ac2d128> Temperature
In Celsius.__get__().... <__main__.Temperature object at 0x7f7f0ac2d128> Temperature
122.0
forth sentence
In Celsius.__get__().... <__main__.Temperature object at 0x7f7f0ac2d128> Temperature
50.0
|