Python与Java不同,不采用关键字修饰成员变量的方式,而是采用_与__的不同组合来实现对变量的约束。总体来说有以下三种:
需要额外注意的是,在python中还有一种以双下划线开始并同样以双下划线结尾的变量,如__name__
,这种为python的特殊变量,有特殊含义,广泛存在于代码中,例如直接在python控制台中敲如下命令:
>>> print dir() ['__builtins__', '__doc__', '__name__', '__package__']
对于一个类也是同样有效的(init同样是双下划线开头并结尾):
class Student(object): def __init__(self, name): self._name = name print "\n".join(dir(Student))
输出如下:
因此在进行变量命名的时候不要用这种特殊写法以免出现重名冲突等问题。
python本身不存在变量修饰符的概念,自然也不是真正意义上的私有变量,而是通过变量重命名的方式实现的。python中叫name mangling
(目的就是以防子类意外重写基类的方法或者属性),即前面加上“单下划线”+类名(例:_Class__object),通过这种方式间接实现了private。下面通过例子验证一下。
class Student(object): def __init__(self, name): self.__name = name s = Student("xiaoming") print "\n".join(dir(s))
输出结果如下:
可以看到中间多了一个_Student__name,这个就是通过name mangling之后的私有变量name。
但是如果此时通过s.__name
去访问,程序并不会报错:
class Student(object): def __init__(self, name): self.__name = name s = Student("xiaoming") s.__name = "zhangsan" print "\n".join(dir(s))
为什么呢?通过控制台输出可以看到答案:
注意与上文代码运行的结果进行一下对比,可以看到多了一个__name
变量,这就是问题所在。当试图使用s.__name = "zhangsan"
去修改一个private变量的时候,实际修改的并不是之前的__name
,而是为Student实例新增了一个叫做__name
的成员变量,所以程序并不会报错,当然,实例中原本的__name
也并没有被修改。务必牢记这是一种错误的写法。