33. 创建可管理的对象属性
在面向对象编程中,我们把方法(函数)看作对象的接口。直接访问对象的属性可能是不安全的,或导致设计上不够灵活,但是使用调用方法在形式上不如访问属性简洁。例如:
circle.get_radius() #调用方法
circle.set_radius(5.0) #繁
circle.radius #访问属性
circle.redius = 5.0 #简
要求:实现在形式上是访问属性,实际上内部调用方法。
解决方案:
使用内置的property()
函数为类创建可管理属性,fget/fset/fdel对象属性访问/设置/删除。
对于
property()
函数:property(fget=None, fset=None, fdel=None, doc=None)
返回property属性。fget是获取属性值的函数。fset是用于设置属性值的函数。fdel是用于删除属性值的函数。并且doc为属性对象创建文档字符串。
class C:
def __init__(self):
self._x = None
def getx(self):
return self._x
def setx(self, value):
self._x = value
def delx(self):
del self._x
x = property(getx, setx, delx, "I'm the 'x' property.")
如果c是C的实例,c.x
将调用getter方法获取属性,c.x = value
将调用setter方法设置属性,del c.x
将调用deleter方法删除属性。
如果给出doc,doc将成为该property属性的文档字符串,否则该property将拷贝fget的文档字符串(如果存在)。
此外,如果property()
函数只定义fget(getter),则定义的属性为只读属性。
方案示例:
import math
class Circle:
def __init__(self, radius):
self.radius = radius
def get_radius(self):
return round(self.radius, 1)
def set_radius(self, radius):
if not isinstance(radius, (int, float)):
raise TypeError('wrong type')
self.redius = radius
@property
# def get_area(self):
def S(self):
return round(self.radius ** 2 * math.pi, 1)
@S.setter
# def set_area(self, s):
def S(self, s):
self.radius = math.sqrt(s / math.pi)
R = property(get_radius, set_radius)
c = Circle(5.712)
c.R = 100.987
print(c.R * 2)c.S = 99.88
print(c.S, c.R, end=’ ‘)
11.4 #结果
99.9 5.6
通过property()
函数定义属性R,来调用get_radius()
和set_radius()
方法。通过@property
装饰器装饰S,达到与定义R属性一样的效果。
还没有评论,来说两句吧...