第七章 面向对象(9):让我们把函数属性做得像一个数据属性 - property装饰器的使用

7.12 property装饰器的使用

意义:本节介绍的装饰器可以让我们把函数属性做得像一个数据属性!

  • 这里我们介绍以下装饰器:
    • @property
    • @func.setter
    • @func.deleter

场景: 当一个数据属性需要通过计算或者处理才能得出的时候,我们需要用函数属性来计算, 这样,调用的时候用户需要调用方法来获得这个属性。 但是对于用户来说,函数属性是用来做事的而不是来获取数据属性的。 这种情况我们该怎么办呢?

这时,我们就可以在这个函数属性上加一个 @property 的装饰器来实现 函数属性→数据属性 的伪装

@property装饰器:

# BMI 体质指数计算例: bmi = 体重 / 身高的平方

class People:
    def __init__(self, name, weight, height):
        self.name = name
        self.weight = weight
        self.height = height
        
    @property  # 装饰器修饰bmi函数属性
    def bmi(self):  # 因为bmi只是一个对象的属性而不是对象的动作,我们不想用方法来调用。
        return self.weight / (self.height ** 2)  # 返回结果

p1 = People('a', 85, 1.78)

print(p1.bmi)  # 如果没有@property装饰器,我们这里需要用p.bmi()来调用。

# 注意:bmi是个方法,所以不能直接赋值
# p.bmi = 3333  # 这个会报错:AttributeError。不过真想对这个方法进行修改,可以用setter,deleter装饰器重写该方法

@func.setter,@func.deleter装饰器:

class People:
    def __init__(self, name):
        self.__name = name
        
    @property  
    def name(self):
        return self.__name
    
    @name.setter  # 设定用装饰器
    def name(self, val):
        if not isinstance(val, str):
            print('名字必须是字符')
            return
        self.__name = val
        
    @name.deleter
    def name(self):
        print('deleter')
        del self.__name  # 删除name属性
        
p1 = People('a')

print(p1.name)

p1.name = 'A'  # 可以(似乎只能)用 = 来赋值,@setter
print(p1.name)

p1.name = 123  # 不符合类型会print

print(p1.__dict__)
del p1.name  # 可以用del来删除, @deleter
print(p1.__dict__)

执行结果:

a
A
名字必须是字符
{'_People__name': 'A'}
deleter
{}

猜你喜欢

转载自www.cnblogs.com/py-xiaoqiang/p/11210452.html
今日推荐