2 深入类的属性
2.1 同名的类属性与实例属性
在使用实例名.属性名应用时,优先引用实例属性
使用类名.属性名时,只能引用类属性
class
ClassAttrDemo1:
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,'属性','值')
class
ClassAttrDemo1:
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 -*-
class
Washer:
def
__init__(self,water=
10
,scour=
2
):
self._water=water
#_water为私有属性
self.scour=scour
self.year=
2012
#方法包装为属性
@property
def
water(self):
return
self._water
#可写
@water.setter
def
water(self,water):
if
0
<water<
200
:
self._water=water
else
:
print
(
"set water failure..."
)
#虚拟属性
@property
def
total_year(self):
return
2017
-self.year
def
set_water(self,water):
self.water=water
def
set_scour(self,scour):
self.scour=scour
def
add_water(self):
print
(
"add water:"
,self.water)
def
add_scour(self):
print
(
"add scour:"
,self.scour)
def
start_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__()让类的实例可以像函数一样调用