Python描述符Descriptor简单使用

实现了__set__(), __get__()或__delete__()的对象,且描述符属性只能定义在类级别。
@property可利用描述符实现。(@classmethod, @staticmethod等也可以用描述符实现)


利用描述符来进行类型检查。
Python中属性引用解析的执行方式,优先级链搜索属性。数据描述符(实现了__set__(), __get__())优先级>实例变量>非数据描述符(只实现__get__())。在下例中实际给属性赋值时, u_0.name='test'等同于type(u_0).__dict__['name'].__set__(u_0, 'test'),取值,访问属性u_.name等同于type(u_0).__dict__['name'].__get__(u_0, type(u_0))

class Field(object):
    _expected_type = type(None)

    def __init__(self, name):
        self.name = name

    def __set__(self, instance, value):
        if not isinstance(value, self._expected_type):
            raise TypeError('excepted %s' % self._expected_type)
        # setattr(instance, self.name, value)
        instance.__dict__[self.name] = value

    def __get__(self, instance, owner):
        if not instance:
            return self
        # getattr(instance, self.name)
        return instance.__dict__[self.name]


class StringField(Field):
    _expected_type = str


class IntField(Field):
    _expected_type = int


class User_0(object):
    name = StringField('name')
    age = IntField('age')

    def __init__(self, name, age):
        self.name = name
        self.age = age

u_0 = User_0(name='JiangW', age=22)
u_0.name = 'test'
print(u_.age)

# TypeError: excepted <class 'int'>
# User_0(name='JiangW', age='22')

其他方式实现类型检查。
利用函数和@property。property实际是一个描述符类,CheckType()方法返回的实际是一个<class 'property'>的对象, 该对象也是实现了__set__(), __get__()。

def CheckType(name, expected_type):
    _name = name

    @property
    def res(self):
        return getattr(self, _name)

    @res.setter
    def res(self, value):
        if not isinstance(value, expected_type):
            raise TypeError('excepted type %s' % excepted_type)
       setattr(self, _name, value)

    return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值