描述符:将某种特殊类型的类的实例,指派给另一个类的属性。
描述符属性方法:
__get__(self, instance, owner) | 用于访问属性,它返回属性的值 |
__set__ (self, instance, value) | 将在属性分配操作中调用,不返回任何内容 |
__delete__ (self, instance) | 控制删除操作,不返回任何内容 |
instance指的就是另一个类的实例对象。
owner指的就是另一个类的类本身。
value指的是实例对象的值。
1. 使用类创建描述符
将描述性类MyDecriptor,指派给Test的属性
>>> class MyDecriptor:
def __get__(self , instance, owner):
print("getting……", self, instance, owner)
def __set__(self , instance, value):
print("setting……", self, instance, value)
def __delete__(self, instance):
print("deleting……", self, instance)
>>> class Test:
x = MyDecriptor()
输出结果:
>>> test = Test()
>>> test.x
getting…… <__main__.MyDecriptor object at 0x0000021464A0DA58> <__main__.Test object at 0x00000214648D2860> <class '__main__.Test'>
>>> test.x = 'lalala'
setting…… <__main__.MyDecriptor object at 0x0000021464A0DA58> <__main__.Test object at 0x00000214648D2860> lalala
>>> del test.x
deleting…… <__main__.MyDecriptor object at 0x0000021464A0DA58> <__main__.Test object at 0x00000214648D2860>
test.x 就是取值操作,使用的是“__get__”函数。返回值包括MyDecriptor类实例对象,Test的实例对象test以及所属的类。
test.x = 'lalala' 是赋值操作,使用的是“__set__”函数,返回值包括MyDecriptor类实例对象,Test的实例对象test以及被赋予的值。
del test.x 就是删除操作
例题:
class C:
def __init__(self, value = 26.0):
self.value = float(value)
def __get__(self, instance, owner):
return self.value
def __set__(self, instance, value):
self.value = float(value)
class F:
# instance是指的下面的类里面的实例
def __get__(self, instance, owner):
return instance.c * 1.8 + 32
def __set__(self, instance, value):
instance.c = (float(value) - 32) /1.8
class Test:
c = C()
f = F()
测试:
>>> t1 = Test()
>>> t1.c = 100
>>> t1.f
212.0
>>> t1.c = 30
>>> t1.f
86.0
>>> t1.f = 100
>>> t1.c
37.77777777777778
2. 使用属性类型创建描述符
还可以使用属性类型的方法。通过使用 property(),可以轻松地为任意属性创建可用的描述符。创建 property()
的语法是 property(fget=None, fset=None, fdel=None, doc=None)
,其中:
- fget:属性获取方法
- fset:属性设置方法
- fdel:属性删除方法
- doc:docstring
class Person(object):
def __init__(self):
self._name = ''
def fget(self):
print ("Getting: %s" % self._name)
return self._name
def fset(self, value):
print ("Setting: %s" % value)
self._name = value.title()
def fdel(self):
print ("Deleting: %s" %self._name)
del self._name
name = property(fget, fset, fdel, "I'm the property.")
测试之后:
>>> p = Person()
>>> p.name = 'haha'
Setting: haha
>>> p.name
Getting: Haha
'Haha'
>>> del p.name
Deleting: Haha
(可以理解为使用“name”封装了“_name”等方法)