如果在一个类中要设置和获取一个成员变量的话,正常的写法应该是以下这种经典的写法。
class Student(object): __slots__ = ('__name', '__age', '__score') def __init__(self, name, age, score = 0): self.__name = name self.__age = age self.__score = score # 获取score def getscore(self): return self.__score # 设置score value def setscore(self, score): if not isinstance(score, int): raise ValueError('Score必须是int类型!') if score < 0 or score > 100: raise ValueError('Score值必须在0=<score<=100') self.__score = score
在实际的应用过程中,如果要get/set score就得如下这种写法:
stu = Student('Wuli', 28) stu.setscore(88) stu.getscore() = 88这样这样写本没有什么错, 但是鉴于在实际的码code的过程中,getfuncname/setfuncname实在是太普通了.
我们可能希望get/set一个值时有更简单的方法(如下),像设置成员变量一样去设置一个变量,又可以检查类型参数,如下:
#设置成员变量 stu.score = 100 #获取成员变量值 stu.score # 报错: AttributeError Traceback (most recent call last) <ipython-input-9-fb8376649a7b> in <module>() ----> 1 stu.__score = 88 AttributeError: 'Student' object has no attribute '__score'
还真可以,因了python有@property 装饰器。我们对前面的代码稍稍做一些修改。
class Student(object): __slots__ = ('__name', '__age', '__score') def __init__(self, name, age, score = 0): self.__name = name self.__age = age self.__score = score # 获取score @property def score(self): return self.__score # 设置score value @score.setter def score(self, score): if not isinstance(score, int): raise ValueError('Score必须是int类型!') if score < 0 or score > 100: raise ValueError('Score值必须在0=<score<=100') self.__score = score
注意一下第1段代码与第2段代码之间的差异, get/set的函数名都变成一样了。
但是上了分别多了一个@property/@score.setter.
@property 加了这个装饰器的funcname相当于getfuncname()@score.setter 加了这个装饰器的funcname相当于setfuncname
自此,你就可以像耍成员变量一样的去耍它们了。
In [15]: stu = Student('wuli2', 28) In [16]: stu.score = 88 In [17]: print(stu.score) 88