访问限制

在Class内部,可以有属性和方法,而外部代码可以通过直接调用实例变量的方法来操作数据,这样,就隐藏了内部的复杂逻辑。

如下图,lisa.score=58,可以修改这个实例的属性。

 

 如果要让内部属性不被外部访问,可以把属性的名称前加上两个下划线__,在Python中,实例的变量名如果以__开头,就变成了一个私有变量(private),只有内部可以访问,外部不能访问,所以,我们把Student类改一改:

class Student(object):
    
    def __init__(self, name, score):
        self.__name = name
        self.__score = score
    
    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))
   
lisa = Student('Lisa Bush', 70)
    
print('lisa.name =', lisa.__name)
运行后打印:
AttributeError: 'Student' object has no attribute '__name'
因为外部不能访问这个属性。

但是如果外部代码要获取name和score怎么办?可以给Student类增加get_nameget_score这样的方法:

class Student(object):
    ...
    def get_name(self):
        return self.__name

    def get_score(self):
        return self.__score

如果又要允许外部代码修改score怎么办?可以再给Student类增加set_score方法:

class Student(object):
    ...

    def set_score(self, score):
        self.__score = score

练习

请把下面的Student对象的gender字段对外隐藏起来,用get_gender()set_gender()代替,并检查参数有效性:

我直接在原来的类的init方法中增加了gender属性。

class Student(object):
    
    def __init__(self, name, score, gender):
        self.__name = name
        self.__score = score
        self.__gender = gender
    
    def print_score(self):
        print('%s: %s' % (self.__name, self.__score))

    def get_grade(self):
        if self.__score >= 90:
            return 'A'
        elif self.__score >= 60:
            return 'B'
        else:
            return 'C'
    def get_name(self):
        return self.__name
    def get_score(self):
        return self.__score
    def set_score(self,score):
        if 0 <= score <= 100:
            self.__score=score
        else:
            raise ValueError('bad score')
    
    def get_gender(self):
        return self.__gender
    def set_gender(self,gender):
        if gender in ('male','female'):
            self.__gender = gender
        else:
            raise ValueError('bad gender')

lisa = Student('Lisa Bush', 70, 'female')

lisa.set_score(90)   
print('lisa.name =', lisa.get_name())

lisa.print_score()

print('grade of Lisa:', lisa.get_grade())
if lisa.get_gender()!='female':
    print('Test failed!')
else:
    lisa.set_gender('male')
    if lisa.get_gender()!='male':
        print('Test failed!')
    else:
        print('Test OK!')
验证OK