通常我们在访问和赋值属性的时候,都是在直接和类(实例的)的__dict__打交道,或者跟数据描述符等在打交道。但是假如我们要规范这些访问和设值方式的话,一种方法是引入复杂的数据描述符机制,另一种恐怕就是轻量级的数据描述符协议函数Property()。它的标准定义是:
property(fget=None,fset=None,fdel=None,doc=None) 前面3个参数都是未绑定的方法,所以它们事实上可以是任意的类成员函数
property()函数前面三个参数分别对应于数据描述符的中的__get__,__set__,__del__方法,所以它们之间会有一个内部的与数据描述符的映射。看一个例子:
class property(object): def __init__(self,x): assert isinstance(x,int),"x=%s must be integer" % x; self.__x=~x; def get_x(self): return ~self.__x; # def set_x(self,x): # self.__x=~x; x=property(get_x); inst=property(10); print inst.x inst.x=16 print inst.x
这个例子在第一次输出10后,第二次将不会输出16,理由是它没有set方法。稍微做下改造:
class property(object): def __init__(self,x): assert isinstance(x,int),"x=%s must be integer" % x; self.__x=~x; def get_x(self): return ~self.__x; def set_x(self,x): self.__x=~x; x=property(get_x,set_x); inst=property(10); print inst.x inst.x=16 print inst.x
这次可以正确的输出10和16了。你甚至还可以加入一个文档描述:
x=property(get_x,set_x,doc='a simple property'); 注意这里要用: print property.x.__doc__ 可以输出a simple property 但如果改为调用print inst.x.__doc__ 则输出int类的描述文档。 像下面这样: int(x[, base]) -> integer Convert a string or number to an integer, if possible. A floating point argument will be truncated towards zero (this does not include a string representation of a floating point number!) When converting a string, use the optional base. It is an error to supply a base when converting a non-string. If the argument is outside the integer range a long object will be returned instead. 理由是property()函数里的doc是与类绑定的