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! ')
    elif (score <0 or score > 100):
    raise ValueError('score must be in [0,100]! ')
    else:
    self.__score = score
    s1 = Student()

    sco = s1.Get_Score()

    print(sco,' ') #由于此时没有设置__score{没有执行set},故而此刻不存在__score,会报错

    s1.Set_Score(100) #嗯,刚刚set了,所以此刻起,s1就有__score了,但是Student依旧不存在__score
    sco = s1.Get_Score()
    print(sco,' ')

    s1.Set_Score(1000) #范围超出了[0,100],报错

    sco = s1.Get_Score()

    print(sco,' ')

    s1.Set_Score('90') #传入score的类型不是int,报错

    sco = s1.Get_Score()

    print(sco,' ')

  • 使用@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!
')
        elif (score <0 or score > 100):
            raise ValueError('score must be in [0,100]!
')
        else:
            self.__score = score
            
s2 = MyStudent()
#print(s2.score,'
') #同样的,class本身没有设置__score,而此处的s1这个instance目前还没有set这个属性
                     #所以,一上来get就会报错
s2.score = 95
print(s2.score,'
') #设置了__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,'
') #p1的__birth还没设置,不可访问
p1.birth = 1995
print(p1.birth,'
')

print(p1.age,'
') #因为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!
')
        elif (width <1 or width > 1366):
            raise ValueError('width must be in [1,1366]!
')
        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,'
')
print(sc1.resolution,'
')

#sc1.width = '1024' #类型不对
#sc1.width = 100000 #大小不对
#sc1.resolution = 1234567 #resolution是只读属性,不可以写
原文地址:https://www.cnblogs.com/LS1314/p/8504464.html