python中@property装饰器的使用

2018-07-09 13次浏览 发表评论

举例定义一个员工类:

class Staff(object):
    """docstring for Staff"""

    def __init__(self, name, ycqts):
        self.__name = name
        self.__ycqts = ycqts

    def get_ycqts(self):
        return self.__ycqts    # 获取出勤天数的方法

    def set_ycqts(self, v):    # 设置出勤天数的方法
        self.__ycqts = v

实例化为一个对象:

s = Staff('sunk', 28)
print(s.get_ycqts())       # => 28

s.set_ycqts(aaa50)
print(s.get_ycqts())       # => aaa50 这明显没有验证有效性

把的Staff类进行修改:

class Staff(object):
    """docstring for Staff"""

    def __init__(self, name, ycqts):
        self.__name = name
        self.__ycqts = ycqts

    def get_ycqts(self):
        return self.__ycqts

    def set_ycqts(self, v):
        if not isinstance(v, int):
            raise ValueError('出勤天数必须是数字')
        elif v < 0 or v > 31:
            raise ValueError('出勤天数必须大于0小于31')
        else:
            self.__ycqts = v

现在出勤天数就不可以随心所欲的设置了:

s.set_ycqts(33)
print(s.get_ycqts())    # => ValueError: 出勤天数必须大于0小于31

上面的例子中s.set_ycqts()s.get_ycqts()没有直接写s.ycqts更方便,python中的@property装饰器可以实现这种写法:

class Staff(object):
    """docstring for Staff"""

    def __init__(self, name, ycqts, card):
        self.__name = name
        self.__ycqts = ycqts
        self.__card = card

    @property
    def ycqts(self):
        return self.__ycqts

    @ycqts.setter
    def ycqts(self, v):
        if not isinstance(v, int):
            raise ValueError('出勤天数必须是数字')
        elif v < 0 or v > 31:
            raise ValueError('出勤天数必须大于0小于31')
        else:
            self.__ycqts = v

    @property
    def card(self):
        return self.__card

把一个getter方法变成属性,只需要加上@property就可以了,此时@property本身又创建了另一个装饰器@ycqts.setter,负责把一个setter方法变成属性赋值,于是,我们就拥有一个可控的属性操作:

s = Staff('sunk', 28, '32012220000212121X')
s.ycqts = 30       # 实际转换为 s.set_ycqts(30)
print(s.ycqts)     # => 30

上面例子上card定义为只读属性,只定义getter方法,不定义setter方法就是一个只读属性:

s.card = '00000000000000000'    # => AttributeError: can't set attribute

card是一个只读属性,不能被重新赋值。

评论

随便说点,聊聊天~