描述符

property ----把函数的调用伪装成对属性的访问

class Movie:
    def __init__(self,title,budget):
        self.title = title
        self.budget = budget


d1 = Movie('电影名称',30)
d1.budget = -100
print(d1.budget)

输出:
-100

你意识到:如果不小心给电影打了负分怎么办?你觉得这是错误的行为,希望Movie类可以阻止这个错误。

我们用@property装饰器指定了一个getter方法,用@budget.setter装饰器指定了一个setter方法。当我们这么做时,每当有人试着访问budget属性,Python就会自动调用相应的getter/setter方法。比方说,当遇到d1.budget = value这样的代码时就会自动调用budget.setter。

class Movie:
    def __init__(self,title,budget):
        self.title = title
        self._budget = budget

    @property
    def budget(self):
        return self._budget
    @budget.setter
    def budget(self,value):
        if value < 0:
            raise ValueError('输入值有误')
        self._budget = value

d1 = Movie('电影名称',30)
d1.budget = -100
print(d1.budget)

输出:
ValueError: 输入值有误

property让我们将自定义的代码同变量的访问/设定联系在了一起,同时为你的类保持一个简单的访问属性的接口。
对property来说,最大的缺点就是它们不能重复使用。
当需要为输入的字段都添加检查时,可以看到代码增加了不少,但重复的逻辑也出现了不少。虽然property可以让类从外部看起来接口整洁漂亮,但是却做不到内部同样整洁漂亮。

描述符是property的升级版,允许你为重复的property逻辑编写单独的类来处理。即把实例属性交给描述符代理,进行判断检测等处理后执行.

类型检测案例:

class Typed:
    def __init__(self,key,expected_type):
        self.key = key
        self.expected_type = expected_type
    def __get__(self, instance, owner):
        return instance.__dict__[self.key]
    def __set__(self, instance, value):
        if not isinstance(value,self.expected_type):
            raise TypeError('%s传入的类型不是%s'%(value,self.expected_type))
        instance.__dict__[self.key] = value
    def __delete__(self, instance):
        print(instance.__dict__.pop(self.key))

class Movie:
    title = Typed('title',str)
    rating = Typed('rating',int)
    runtime = Typed('runtime',int)
    budget = Typed('budget',int)
    gross = Typed('gross',int)
    def __init__(self, title, rating, runtime, budget, gross):
        self.title = title
        self.rating = rating
        self.runtime = runtime
        self.budget = budget
        self.gross = gross

d1 = Movie('电影名称','dg',24,535,6346)

print(d1.__dict__)

抛出错误:
dg传入的类型不是<class ‘int’>

描述符优先级(本质是底层字典的覆盖):

类属性>数据描述符>实例属性>非数据描述符>__ getattr __

同时具有__ get __ 属性和__ set __ 属性的新式类是数据描述符,
只具有__ get __ 属性的新式类是非数据描述符

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值