关于描述器
- 概念和作用:描述器是一个对象,可以描述一个属性的操作;其作用是对属性的操作做验证和过滤,如对一个人的年龄赋值时,不能赋值为负数,这是需要验证和过滤,但由于属性数量多,不能在赋值前进行验证,所以用到描述器,每次验证时就会进入描述器中进行相关操作
- 描述器的定义方式一:使用property将操作方法与属性进行关联,即可在操作属性时自动进行相关方法执行
class Person(object):
def __init__(self):
self.__age = 18
def setAge(self, value):
self.__age = value
def getAge(self):
return self.__age
age = property(getAge, setAge)
p = Person()
print(p.age)
p.age = 20
print(p.age)
- 描述器的定义方式二:对方式一进行优化,即多个属性时,由于操作内容不同,在主类中代码会过于繁琐,为简化代码,将属性的操作方法封装到类中,在主类中对方法类的实例对象进行操作即可
class Age(object):
def __get__(self, instance, owner):
print("get")
pass
def __set__(self, instance, value):
print("set")
pass
def __delete__(self, instance):
print("del")
pass
class Person(object):
def __init__(self):
pass
age = Age()
p = Person()
print(p.age)
p.age = 10
print(p.age)
del p.age
- 影响描述器运行的几个细节:1.描述器只有在新式类中才能被执行,描述器类也要是新式类;2.在方式二中,描述器类在主类中创建的实例对象属于主类的类属性,这时对其操作可以有两种方式,使用实例操作p.age和使用类操作Person.age,这里需要注意的是,只能使用实例操作p.age才有效,使用类操作Person.age无效
- 被操作属性值的存储问题:描述器定义方式二中有描述器类和主类两个类,当操作由主类产生的两个实例对象的同一个属性时,这个属性要被赋予不同的值,即两个实例赋值互不影响,这就要研究属性值的存储问题。由于操作的时同一个属性,所以进入的是同一个描述器类,如果将值存储在描述器类产生的实例上,由于存储地址相同,后面的赋值会覆盖前面的赋值;而主类产生的两个实例对象不同,分配了不同内存,因此,应将属性值存储在主类的实例中