property()
用于设置成员属性的修饰符 格式:成员属性 = property(获取的方法,设置的方法,删除的方法)
例子:
class Room:
# area = Lazy Property('area') @LazyProperty做的事情
def __init__(self, name, width, length):
self.name = name
self.width = width
self.length = length
@LazyProperty # area = LazyProperty(area)
def area(self):
return self.width * self.length
@property # area1 = property(area1)
def area1(self):
return self.width * self.length
#实例调用
r1 = Room('房间', 1, 1)
print(r1.area.func(r1))
print(r1.area)
print(r1.__dict__)
#类调用
print(Room.area)
print(Room.__dict__)
print(Room.area.__name__)
-----------------------------------------------------------------------------------------------------------------------
property用法补充
class Foo():
@property
def AAA(self): #第一个必须依赖于静态属性
print('get的时候运行我啊')
@AAA.setter
def AAA(self, val):
print('set的时候运行我啊', val)
if not isintstance(value,str):
raise TypeError('必须是字符串类型')
self.DouNiWan = value
@AAA.deleter
def AAA(self):
print('del的时候运行我啊')
#只有在属性AAA定义property后才能定义AAA.setter,AAA.deleter
f1 = Foo()
f1.AAA
f1.AAA = 'aaa'
del f1.AAA
---------------------------------------------------------------------------------------------------------------------
class Foo():
def get_AAA(self):
print('get的时候运行我啊')
def set_AAA(self, val):
print('set的时候运行我啊', val)
def del_AAA(self):
print('del的时候运行我啊')
AAA = property(get_AAA, set_AAA, del_AAA) #属性必须一一对应,获取-设置-删除
------------------------------------------------------------------------------------------------------------------------
案例:
利用描述符完成一个自定值@property,实现延迟计算(本质就是一个函数属性利用装饰器原理做成一个描述符:类的属性字典中函数名为key,value为描述符类产生的对象)
class Goods:
def __init__(self):
# 原价
self.original_price = 100
# 折扣
self.discount = 0.8
@property
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 # 删除商品原价
# print(obj.price)
案例:
利用property实现类型检测功能
#第一关:
class People:
def __init__(self,name):
self.name=name
@property
def name(self):
return self.name
p1=People('alex') #property自动实现了set和get方法属于数据描述符,比实例属性优先级高,所以你这面写会触发property内置的set,抛出异常
#第二关:修订版
class People:
def __init__(self,name):
self.name=name #实例化就触发property
@property
def name(self):
# return self.name #无限递归
print('get------>')
return self.DouNiWan
@name.setter
def name(self,value):
print('set------>')
self.DouNiWan=value
@name.deleter
def name(self):
print('delete------>')
del self.DouNiWan
p1=People('alex') #self.name实际是存放到self.DouNiWan里
print(p1.name)
print(p1.name)
print(p1.name)
print(p1.__dict__)
p1.name='egon'
print(p1.__dict__)
del p1.name
print(p1.__dict__)
#第三关:加上类型检查
class People:
def __init__(self,name):
self.name=name #实例化就触发property
@property
def name(self):
# return self.name #无限递归
print('get------>')
return self.DouNiWan
@name.setter
def name(self,value):
print('set------>')
if not isinstance(value,str):
raise TypeError('必须是字符串类型')
self.DouNiWan=value
@name.deleter
def name(self):
print('delete------>')
del self.DouNiWan
p1=People('alex') #self.name实际是存放到self.DouNiWan里
p1.name=1
print(p1.__dict__)