#比较1 - 暴露真正属性值,直接修改属性值 #优点:直接修改属性,很方便;缺点:直接暴露修改属性值容易出现错误 class Student(object): def __init__(self, name): #必选属性name,输入name属性值才可以创建实例 self.name = name __slots__ = ('name', 'score') #设置类只有2种属性 Student.name #输出<member 'name' of 'Student' objects>,‘member’说明'name'是一个属性 s = Student('lisa') #创建实例s s.score = 90 #只要知道属性的名称就可以通过等式修改任意属性
#比较2 - 保护真正属性名称,使用实例方法修改属性值 #优点:保护属性值不会被随意修改;缺点:使用实例方法比较复杂,没有直接修改属性方便 class Student(object): def __init__(self, name): #必选属性name,输入name属性值才可以创建实例 self.name = name __slots__ = ('name', 'real_score') #真正的属性名称为real_score def get_score(self): #定义读取属性real_score的方法 return self.real_score def set_score(self, value): #定义修改属性real_score的方法 self.real_score = value Student.get_score #输出<function __main__.Student.get_score(self)>,说明'get_score'是类的函数 s = Student('lisa') #创建实例s s.score = 90 #失败,因为score并不是真正的属性名称 s.get_score #输出<bound method Student.get_score of <__main__.Student object at 0x地址>>,说明'get_score'是实例的方法 s.set_score(90) #通过实例方法去修改属性,其实并不知道修改的是哪个属性,自能通过doc说明来理解 s.get_score() #输出90,通过实例方法去读取属性 s.real_score = 100 #如果知道真实的属性名称为'real_score',仍然可以直接修改属性值 s.real_score #输出100,如果知道真实的属性名称为'real_score',仍然可以通过属性直接读取
#比较3 - 通过property来保护真正属性名称,并且模拟属性方法来修改属性值 class Student(object): def __init__(self, name): #必选属性name,输入name属性值才可以创建实例 self.name = name __slots__ = ('name', 'real_score') #真正的属性名称为real_score @property #通过property装饰器(或者property函数)来创建一个模拟属性‘score’,并且定义读取模拟属性’score‘的方法 def score(self): return self.real_score @score.setter #property函数默认会创建(getter, setter, deleter三个子函数),分别对应模拟属性‘score’的读取,修改和删除 def score(self, value): self.real_score = value @property def grade(self): if self.real_score > 90: return 'A' elif self.real_score > 60: return 'B' else: return 'C' Student.name #可见真正的属性’name‘和'real_score'的类型为member Student.score #通过@property生成的模拟属性'score'类型为property,并不是member Student.name.__get__ #输出<method-wrapper '__get__' of member_descriptor object at 0x地址>,属性'name'的读取是通过方法 Student.score.__dir__() #可以看见@property输出了[ 'getter','setter','deleter']函数 Student.score.getter #输出<function property.getter>,属性'score'的读取是通过函数 s = Student('lisa') #创建实例s s.score = 100 #实际调用的是score.setter, 如果前面定义部分没有@score.setter则score会变为只读属性 s.score #输出100,实际调用的是score.getter s.grade #输出'A' s.grade = 'B' #输出AttributeError: can't set attribute,该模拟属性'grade'只读,不可修改
Sign in to make a reply
采蘑菇的lucas_688