property()函数
有了之前的描述符,property()函数也就好理解了。
property()函数也是处理属性相关的问题的(访问、赋值、删除和文字说明)。
property()函数语法如下
property(fget = None, fset = None, fdel = None, doc = None)
property()函数的四个参数fget、fset、fdel和doc都是函数对象,分别执行属性的访问、赋值、删除和文字说明这四个操作,它们的默认值都是None。也就是说,如果没有给出明确的定义,就不能执行相应的操作。比如说property(fget)(fget已定义),就是可以进行属性访问,不能进行属性赋值和删除属性,也不能查看属性的文字说明。
接下来是书中四个例子。
#-*-coding: utf-8-*- # 建立只读的整型属性 class ProtectAndHideX(object): def __init__(self, x): assert isinstance(x, int), "'x' must be an interger!" self.__x = ~x # 实例属性__x为x的取反 def get_x(self): return ~self.__x # 对__x取反回来,就是实例化时传入的参数x x = property(get_x) if __name__ == "__main__": # inst = ProtectAndHideX('foo') # 显然引发断言异常 inst = ProtectAndHideX(10) print 'inst.x =', inst.x # inst.x = 20 # 不能将inst.x设置成20,这是因为property()函数中,fset = None,即无法对属性赋值#-*-coding: utf-8-*- class HideX(object): def __init__(self, x): self.__x = ~x def get_x(self): return ~self.__x def set_x(self, x): # 这样子写可以允许访问该方法,即inst.set_x(40)是可以的,同理get_x()也一样。 assert isinstance(x, int), "'x' must be an integer!" self.__x = ~x x = property(get_x, set_x) if __name__ == "__main__": inst = HideX(20) print inst.x inst.x = 30 # 这回定义了set_x方法,即定义了属性赋值方法,就可以对属性进行赋值了。 print inst.x # del inst.x # 没有定义fdel,显然不能删除实例属性inst.x #-*-coding: utf-8-*- from math import pi def get_pi(dummy): return pi class PI(object): pi = property(get_pi, doc = 'Constant "pi"') if __name__ == "__main__": inst = PI() print inst.pi print PI.pi.__doc__ #-*-coding: utf-8-*- class HideX(object): def __init__(self, x): self.x = x @property def x(): def fget(self): return ~self.__x def fset(self, x): assert isinstance(x, int), "'x' must be an integer!" self.__x = ~x return locals() # 包含所有(函数/方法)名和对应对象的字典 if __name__ == "__main__": inst = HideX(20) print inst.x # 为什么运行时属性错误? inst.x = 30 print inst.x 最后一个例子不知道是怎么回事。暂时放着,以后回头再看。