2 深入类的属性
2.1 同名的类属性与实例属性
在使用实例名.属性名应用时,优先引用实例属性
使用类名.属性名时,只能引用类属性
classClassAttrDemo1:
a=10
def__init__(self):
self.a=20
self.b=20
cad1=ClassAttrDemo1()
print("example
attribute:",cad1.a)
print("class
attribute:",ClassAttrDemo1.a)
print("error:",ClassAttrDemo1.b)
2.2 属性访问的特殊方法(反射)
字符串操作类的属性/方法
主要工具函数:has_attr(obj_name,'属性')、set_attr(obj_name,'属性','值')、get_attr(obj_name,'属性','值')
classClassAttrDemo1:
a=10
def__init__(self):
self.a=20
self.b=20
cad1=ClassAttrDemo1()
# print("example attribute:",cad1.a)
# print("class attribute:",ClassAttrDemo1.a)
#print("error:",ClassAttrDemo1.b)
print("example
attribute value:",getattr(cad1,'a'))
setattr(cad1,'a',80)
print("changed
attribute value:",getattr(cad1,'a'))
print("attributexit:",hasattr(cad1,'c'));
2.3 属性包装
将方法包装为属性,隐藏相关实现(控制属性类型或范围、虚拟属性)
三种属性操作:@property(可读)、@<property-name>.setter(可写)、@<property-name>.delete(可删除)
# -*- coding:utf-8 -*-
classWasher:
def__init__(self,water=10,scour=2):
self._water=water#_water为私有属性
self.scour=scour
self.year=2012
#方法包装为属性
@property
defwater(self):
returnself._water
#可写
@water.setter
defwater(self,water):
if0<water<200:
self._water=water
else:
print("set
water failure...")
#虚拟属性
@property
deftotal_year(self):
return2017-self.year
defset_water(self,water):
self.water=water
defset_scour(self,scour):
self.scour=scour
defadd_water(self):
print("add
water:",self.water)
defadd_scour(self):
print("add
scour:",self.scour)
defstart_wash(self):
self.add_water()
self.add_scour()
print("start
wash ...")
if__name__ =='__main__':
w=Washer(20,5)
print(w.water)
w.water=25
print(w.water)
w.water=222
print(w.water)
print(w.total_year)
2.4 描述符
实现特殊协议方法的类作为另一个类的类属性
拦截和控制属性访问,并且可以重复使用
特殊协议方法如下:__set__()、__get__()、__delete__()
class
NonNegative:
def
__init__(self,default=0):
self.default=default
def
__set__(self,instance,val):
if
val>=0:
self.default=val
else:
print("The
value must be positive")
def
__get__(self,instance,owner):
return
self.default
def
__delete__(self,instance):
pass
class
Movie:
rating=NonNegative()
price=NonNegative()
def
__init__(self):
pass
if
__name__ ==
'__main__':
m=Movie()
print(m.rating)
m.price=10
print(m.price)
m.price=-5
print(m.price)
分类:数据描述符(实现所有特殊协议方法)、非数据描述符(实现部分特殊协议方法)
注:所有的类成员函数都是非数据描述符
同名的数据的实例属性和非数据描述符(方法为例)访问的优先级,同名实例属性会掩盖或者隐藏方法
__call__()让类的实例可以像函数一样调用