19-面向对象之语法(4)
1. 使用 @property
-
原始的实现访问限制的方法:先设置私有属性,再内部编写get(),set(),外部只能访问set和get
class Student(object):
def Get_Score(self):
return self.__score
def Set_Score(self, score): #python此处会动态地私有属性__score {如果没有调用set,那就没有__score}
if not isinstance(score,int):
raise ValueError('score must be a int!\n')
elif (score <0 or score > 100):
raise ValueError('score must be in [0,100]!\n')
else:
self.__score = score
s1 = Student()sco = s1.Get_Score()
print(sco,'\n') #由于此时没有设置__score{没有执行set},故而此刻不存在__score,会报错
s1.Set_Score(100) #嗯,刚刚set了,所以此刻起,s1就有__score了,但是Student依旧不存在__score
sco = s1.Get_Score()
print(sco,'\n')s1.Set_Score(1000) #范围超出了[0,100],报错
sco = s1.Get_Score()
print(sco,'\n')
s1.Set_Score('90') #传入score的类型不是int,报错
sco = s1.Get_Score()
print(sco,'\n')
-
使用@property简化"调用函数"这一部分:
即把调用get()和set()简化成对属性的的获取和设置
同时也能把set()和get()简化成“装饰器+属性()”,无需定义Get_Score()和Set_Score()
class MyStudent(object):
@property #对score进行读操作
def score(self):
return self.__score
@score.setter #对score进行写操作
def score(self,score):
if not isinstance(score,int):
raise ValueError('score must be a int!\n')
elif (score <0 or score > 100):
raise ValueError('score must be in [0,100]!\n')
else:
self.__score = score
s2 = MyStudent()
#print(s2.score,'\n') #同样的,class本身没有设置__score,而此处的s1这个instance目前还没有set这个属性
#所以,一上来get就会报错
s2.score = 95
print(s2.score,'\n') #设置了__score之后,当然就能get了。
#s2.score = 195 #范围超出了[0,100],报错
#s2.score = '95' #类型不是it,报错
#定义只读属性:只定义getter方法,不定义setter方法就是一个只读属性:
class People(object):
@property #允许对__birth的读操作
def birth(self):
return self.__birth
@birth.setter #允许对__birth的写操作
def birth(self, birth):
self.__birth = birth
@property #允许对__age的读操作
def age(self):
return 2018 - self.__birth #当前的年份减去出生年份,即为粗糙的age
#不设置@age.setter以及相应的def age() ... ,等于说age只读{不可写}
p1 = People()
#print(p1.birth,'\n') #p1的__birth还没设置,不可访问
p1.birth = 1995
print(p1.birth,'\n')
print(p1.age,'\n') #因为age内部实现的原因,只要有birth和当前年份,就有age,所以直接get
2. 作业:给一个Screen的对象{即instance}加一个width,height的attribution,{均是可读写},以及一个只读的attribution:resolution
class Screen(object):
@property #读
def width(self):
return self.__width
@width.setter #写
def width(self,width): #先对width做两个测试:1)int 2)[1,1366]
if not isinstance(width,int):
raise ValueError('width must be a int!\n')
elif (width <1 or width > 1366):
raise ValueError('width must be in [1,1366]!\n')
self.__width = width
@property
def height(self):
return self.__height
@height.setter
def height(self,height):
self.__height = height
@property #resolution为只读的attribution
def resolution(self):
return 786432
sc1 = Screen()
sc1.width = 1024
sc1.height = 750
print(sc1.width,sc1.height,'\n')
print(sc1.resolution,'\n')
#sc1.width = '1024' #类型不对
#sc1.width = 100000 #大小不对
#sc1.resolution = 1234567 #resolution是只读属性,不可以写