目标:
理解通过内置函数property() 及 __getattr__
创建属性的过程。
实验过程
Python 2.7.12 (default, Nov 19 2016, 06:48:10)
[GCC 5.4.0 20160609] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> class bird(object):
... feather = True
...
>>> class chicken(bird):
... def __init__(self,age):
... self.age = age
... def getAdult(self):
... if self.age>10: return True
... else: return False
... fly = False
... adult = property(getAdult)
...
>>> summer = chicken(2)
>>>
>>> print summer.__dict__
{'age': 2}
>>> print summer.adult
False
>>> print summer.age
2
>>> print summer.fly
False
>>> print summer.feather
True
>>>
>>> print summer.__class__ # 追溯对象的类
<class '__main__.chicken'>
>>> print chicken.__base__ # 追溯类的父类
<class '__main__.bird'>
>>> print bird.__base__ # 追溯父类的父类
<type 'object'>
>>> print object.__base__
None
>>>
>>> class num(object):
... def __init__(self, value):
... self.value = value
... def getNeg(self):
... return -self.value
... def setNeg(self, value):
... self.value = -value
... def delNeg(self):
... print "value deleted"
... del self.value
... neg = property(getNeg, setNeg, delNeg, "I am negative")
...
>>> x = num(1.1)
>>> print x.neg
-1.1
>>> x.neg = -22
>>> print x.value
22
>>> print num.neg.__doc__
I am negative
>>> del x.neg
value deleted
>>> print x.value
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
AttributeError: 'num' object has no attribute 'value'
>>> x.neg
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in getNeg
AttributeError: 'num' object has no attribute 'value'
>>> print x.neg
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 5, in getNeg
AttributeError: 'num' object has no attribute 'value'
>>>
通过__getattr__(self, name)
可用来查询即时生成的属性。当通过__dict__
方法无法找到该属性,那么Python会调用对象的__getattr__
方法,来即时生成该属性。
>>> class bird(object):
... feather = True
...
>>> class chicken(bird):
... fly = False
... def __init__(self, age):
... self.age = age
... def __getattr__(self, name):
... if name == 'adult':
... if self.age >1.0: return True
... else: return False
... else: raise AttributeError(name)
...
>>> summer = chicken(2)
>>>
>>> print summer.adult
True
>>> summer.age = 0.5
>>>
>>> print summer.adult
False
>>> print summer.male
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 9, in __getattr__
AttributeError: male
>>>
结论
在class中通过 property函数定义类属性(设置getter, setter和del方法),之后,在对象中即可动态操作这些属性。这些属性(property)不同于类或对象的特性(attribute),后者静态保存于对象的__dict__
中。
通过__getattr__
可以将所有的即时生成属性放在同一个函数中处理。