# 修改与删除@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 # 这里就会报错