2. 特性属性property

特性属性是封装方法之一。

什么是特性属性

特性属性(property)是模拟出来的类属性,它将对象对特性属性的操作映射成对方法调用。从而实现对属性操作的控制。

内置类 property 的构造函数

property(fget=None, fset=None, fdel=None, doc=None)

参数说明

示例

第一步:写一个圆形的类。

class Circle:  # 圆类
    def __init__(self, r=1):
        self.radius = r  # 半径

c = Circle(10)
print('圆的半径:', c.radius)
c.radius = -100
print('圆的半径:', c.radius)
del c.radius
print('圆的半径:', c.radius)

上述程序对 圆的半径 radius 赋值为 -100 是错误的。且用 del 语句可以删除 radius 属性,导入后面程序无法正常运行。

第二步:改进上述程序,将半径改为私用属性。然后用方法 set_radius 和 get_radius 对半径进行操作。

# 特性属性示例

class Circle:  # 圆类
    def __init__(self, r=1):
        self.__radius = r  # 半径
    def get_radius(self):
        return self.__radius
    def set_radius(self, r):
        if r < 0:
            raise ValueError('圆的半径不允许小于零!')
        self.__radius = r
    def del_radius(self):
        print('不允许删除圆的半径')
    radius = property(get_radius, set_radius, del_radius, '半径')

c = Circle(10)
print('圆的半径:', c.get_radius())
c.set_radius(-100)  # 报错
print('圆的半径:', c.radius)

上述程序能保证半径属性不被删除,且不能把半径设置为负数。但方法调用比较麻烦,不如直接使用属性方便。

第三步:改进上述程序,创建一个特性属性 radius, 让其对此属性取值调用 get_radius,赋值调用 set_radius,删除调用 del_radius 什么都不做。

# 特性属性示例

class Circle:  # 圆类
    def __init__(self, r=1):
        self.__radius = r  # 半径
    def get_radius(self):
        return self.__radius
    def set_radius(self, r):
        if r < 0:
            raise ValueError('圆的半径不允许小于零!')
        self.__radius = r
    def del_radius(self):
        print('不允许删除圆的半径')
    radius = property(get_radius, set_radius, del_radius, '半径')

c = Circle(10)
# print('圆的半径:', c.get_radius())
# c.set_radius(-100)
print('圆的半径:', c.radius)
# c.radius = -100
# print('圆的半径:', c.radius)
del c.radius
print('圆的半径:', c.radius)

使用 radius 属性既方便,有可以控制赋值的范围,完美解决上述所有的问题。