修改与删除@property封装的数据属性

# 修改与删除@property封装的数据属性

# 原始通过@property实现的功能:将类中定义的函数属性,通过装饰器@property将其封闭成数据属性,这时是不能删除和修改这个数据属性的

class Room:
    def __init__(self, name, width, length):
        self.name = name
        self.width = width
        self.length = length

    @property
    def area(self):
        return self.width * self.length


r1 = Room('厨房', 10, 4)
print(r1.area)


r1.area = 100  # AttributeError: can't set attribute
del r1.area  # AttributeError: can't delete attribute


# @property补充,可以修改和删除封装后的属性
class Goods:
    def __init__(self):
        self.original_price = 100  # 原价
        self.discount = 0.8  # 折扣

    @property  # 这个必须放在setter和deleter的前面,否则不能修改下面的两种方法
    def price(self):
        new_price = self.original_price * self.discount  # 实际价格=原价*折扣
        return new_price

    @price.setter
    def price(self, value):
        self.original_price = value

    @price.deleter
    def price(self):
        del self.original_price


obj = Goods()
print(obj.price)  # 获取价格
obj.price = 200  # 修改原价
print(obj.price)
del obj.price  # 删除原价


# 以上的写法也可以这样写

class Goods:
    def __init__(self):
        self.original_price = 100  # 原价
        self.discount = 0.8  # 折扣

    def get_price(self):
        new_price = self.original_price * self.discount  # 实际价格=原价*折扣
        return new_price

    def set_price(self, value):
        self.original_price = value

    def del_price(self):
        del self.original_price

    price = property(get_price, set_price, del_price)  # 顺序必须为get、set、del


obj = Goods()
print(obj.price)  # 获取价格
obj.price = 200  # 修改原价
print(obj.price)
del obj.price  # 删除原价



# 用@property实现的数据类型检测
class People:
    def __init__(self, name):
        self.name = name  # 实例化就触发property

    @property
    def name(self):
        # return self.name #无限递归
        return self.newname

    @name.setter
    def name(self, value):
        if not isinstance(value, str):
            raise TypeError('名字必须为字符串')
        self.newname = value

    @name.deleter
    def name(self):
        del self.newname


p1 = People('张三')  # self.name实际是存放到self.newname中
p1.name = 1  # 这里就会报错

 

posted @ 2018-08-14 00:10  四十不惑的编程之路  阅读(398)  评论(0编辑  收藏  举报