描述符是描述类A的实例对象a 在另一个类B中实例描述对象a, 再实例化B的对象b后,b就可以通过操作a来达到一些A中定义好的方法 如get set del。
简单例子:
class MyDecription:
def __get__(self, instance, owner): #self是自己的MD实例对象 instance是被描述的实例对象test owner是test类
print('getting', instance, self, owner)
def __set__(self, instance, value):
print('setting', self, instance, value)
def __delete__(self, instance):
print('delling', self, instance)
class Test:
x = MyDecription() #描述符
test = Test()
test.x
print('-'*30)
test.x = 'x-man'
print('-'*30)
输出:
getting <__main__.Test object at 0x00000190199BACA0> <__main__.MyDecription object at 0x00000190199BBFD0> <class '__main__.Test'>
------------------------------
setting <__main__.MyDecription object at 0x00000190199BBFD0> <__main__.Test object at 0x00000190199BACA0> x-man
------------------------------
?机制例子:逐行解读
class MyProperty:
def __init__(self, fget=None, fset=None, fdel=None): #运行顺序第4 self = x
self.fget = fget
self.fset= fset
self.fdel = fdel
def __get__(self, instance, owner):
return self.fget(instance) #x.getx(c)
def __set__(self, instance, value): #运行顺序第8
self.fset(instance, value) #运行顺序第9 x.setx(c, 5)
def __delete__(self, instance):
self.__delete__(instance)
class C:
def __init__(self):
self._x = 1 #运行顺序第2 c._x = 1
def getx(self): #运行顺序第6 返回_x = 1
return self._x
def setx(self, value):
self._x = value #运行顺序第10 c._x = 5
def delx(self):
del self._x
x = MyProperty(getx, setx, delx) #运行顺序第3
c = C() #运行顺序第1
print(c._x) #运行顺序第5 激活get方法
c.x = 5 #运行顺序第7 调用修饰函数的set方法
print(c._x) #运行顺序第11 调用c的getx方法 返回c._x
摄氏度华氏度互相转换的例子:?
class Celssius:
def __init__(self, value = 26.0): #3
self.value = float(value) #4 cel.value = float(value)
def __get__(self, instance, owner): #13
print(self.value, '调用Cel的get')
return self.value
def __set__(self, instance, value): #7 cel, temp, 30
print('调用cel的set') #8
self.value = float(value) #9 cel.value = float(30)
class Fahrenheit:
def __get__(self, instance, owner): #11 fah, temp, Temperature
print(instance.cel * 1.8 + 32) #12 temp.cel
return instance.cel * 1.8 + 32 #14
def __set__(self, instance, value):
instance.cel = (float(value) - 32) / 1.8
class Temperature:
cel = Celssius() #2
fah = Fahrenheit() #5
temp = Temperature() #1
temp.cel = 30 #6 调用修饰的set
temp.fah #10 获取fah的get
temp.fah = 90
temp.cel
??
|