描述符

"""
#描述符:描述符是一种新式类,也只能描述新式类。
    把实现了__get__(),__set__(),__delete__()其中任意一个方法的类称之为描述符
#   数据描述符:包含__get__(),__set__()这两种
#   非数据描述符:只有__get__()这个方法
"""
class Foo:
    def __set__(self, instance, value):    #instance:被描述的实例,value:被描述的实例属性
        print("执行set")
    def __get__(self, instance, owner):    #owner:被描述的实例属于哪个类
        print("执行get")
    def __delete__(self, instance):
        print("执行delete")

#描述符:是用来代理另外一个类的属性,必须把描述符定义成这个类中的属性,不能放在构造函数中
class Student:
    name = Foo()
    def __init__(self,name,age):
        self.name = name
        self.age = age

# Student.name = "x"         #类属性
p1 = Student("ss",22)
p1.name                     #实例属性
"""
使用描述符必须遵循优先级:
    类属性 > 数据描述符 》 实例属性 》 非数据描述符 》找不到属性触发__getattr__()
"""
#Python是一个弱类型语言,可以利用描述符做一个限制输入类型

class Typed:
    def __init__(self,key,expected_type):
        self.key = key
        self.expected_type = expected_type

    def __set__(self, instance, value):
        print("执行set")
        print(value)
        if not isinstance(value,self.expected_type):        #对实例的属性进行判断
            raise TypeError("错误,请输入%s类型" %self.expected_type)
        instance.__dict__[self.key] = value        #通过对属性字典操作,将内容添加进去

    def __get__(self, instance, owner):
        print("执行get")
        return instance.__dict__[self.key]

    def __delete__(self, instance):
        print("执行delete")

class People:
    name = Typed("name",str)
    age = Typed("age",int)
    def __init__(self,name,age):
        self.name = name
        self.age = age

p1 = People("ss",22)
print(p1.__dict__)
p1.name
print(p1.name)

 

posted @ 2019-05-15 00:40  saber゛  Views(211)  Comments(0)    收藏  举报