在C++和java中是通过pubilc、protected和private几个关键字限制类成员的外部访问权限的。而golang则用首字母的大小写区分。
对于python中,如果一个类的成员以两个下划线开头(内置方法和变量除外)则他不允许被外部访问。
eg1
class Student(object):
def __init__(self, name):
self.__name = name
s = Student("xh")
print(s.__name)
当我们尝试范围这个成员的时会报错
Traceback (most recent call last):
File "d:\code\python\tests\访问限制.py", line 6, in <module>
print(s.__name)
AttributeError: 'Student' object has no attribute '__name'
但是这种隐藏方式的实现十分简单,在cpython中,只是简单把这个变量名替换成了 _类名__成员名
的形式
eg2
class Student(object):
def __init__(self, name):
self.__name = name
s = Student("xh")
# print(s.__name)
print(s.__dict__)
print(s._Student__name)
输出
{'_Student__name': 'xh'}
xh
解释器会直接把此类名称替换后执行。那么问题来了,如果我类中已经有一个这种名字的成员变量呢
eg3
class Student(object):
def __init__(self, name):
self._Student__name = 'test'
self.__name = name
s = Student("xh")
# print(s.__name)
print(s.__dict__)
print(s._Student__name)
输出
{'_Student__name': 'xh'}
xh
eg4
class Student(object):
def __init__(self, name):
self.__name = name
self._Student__name = 'test'
s = Student("xh")
# print(s.__name)
print(s.__dict__)
print(s._Student__name)
输出
{'_Student__name': 'test'}
test
所以,可以理解为,在执行之前,解释器进行了简单的名称替换,然后依次执行