python中有时候需要对定义的属性/方法添加一些限制,或者进行一些运算。比如定义一个圆,给定半径,那么直径和面积都会随之而定。
下面这个例子是在SF python meetup上Simeon Franklin给的一个小作业
"""
Properties let us intercept attribute access, sneaking in a function
call where it looks like we merely lookup or set an attribute on an
object.
The Circle class below is broken: its constructor takes a radius
argument
>>> c = Circle(10)
and calculates the diameter
>>> c.diameter
20
But what if you changed the radius? Now the diameter would be incorrect!
Fix the class so that the diameter and radius are kept in sync.
>>> c.radius = 5
>>> c.diameter
10
>>> c.diameter = 12
>>> c.radius
6
"""
import math
class Circle(object):
def __init__(self, radius):
self._radius = radius
self._diameter = 2 * radius
self._area = math.pi * radius ** 2
#定义radius的属性,由radius怎么来求出diameter和area
@property
def radius(self):
return self._radius
#让这个属性可写,如果没有下面的@.setter,那么radius就是一个只读属性
@radius.setter
def radius(self, radius):
self._radius = radius
self._diameter = 2 * radius
self._area = math.pi * radius ** 2
#同样,定义一个diameter属性,以及怎么由此求出半径和面积
@property
def diameter(self):
return self._diameter
@diameter.setter
def diameter(self, diameter):
self._diameter = diameter
self._radius = diameter / 2
self._area = math.pi * (diameter / 2) ** 2
#给定面积求出相应的半径和直径
@property
def area(self):
return self._area
@area.setter
def area(self, area):
self._area = area
self._radius = math.sqrt( area / math.pi)
self._diameter = 2 * math.sqrt( area / math.pi)
#如果只有@property而没有对应的@.setter属性,那就是定义了一个只读的属性