![Python程序设计案例课堂](https://wfqqreader-1252317822.image.myqcloud.com/cover/463/26943463/b_26943463.jpg)
上QQ阅读APP看书,第一时间看更新
6.9 类的封装
所谓类的封装(encapsulation),就是类将其属性(变量与方法)封装在该类内,只有该类中的成员可以使用该类中的其他成员。这种被封装的变量与方法,称为该类的私有变量(private variable)和私有方法(private method)。
Python类中的所有变量与方法都是公用的(public)。只要知道该类的名称与该变量或方法的名称,任何外部的对象都可以直接存取类中的属性与方法。
如下例所示,x是myClass类的实例变量,name是myClass类的变量。利用x.name就可以存取到myClass类中的name变量。
>>> class myClass: def __init__(self): self.name = None >>> x = myClass() >>> x.name = "Andy" >>> a = x.name >>> print (a) Andy
1.封装Python类的原则
要做到类的封装,Python提供以下两个原则。
(1)属性(变量与方法)名称的第一个字符如果是单底线,则此属性视为类的内部变量,外面的变量不可以引用此属性。
(2)属性(变量与方法)名称的前两个字符如果都是单底线,则编译时属性名称attributeName会被改成_className_attributeName, className是该类的名称。由于属性名称之前加上了类的名称,所以与类中原有的属性名称有差异。
这两个原则只是提供作为参考,Python类中的所有属性仍然都是公用(public)的。只要知道类与属性的名称,仍然可以存取类中的所有属性。例如:
>>>class myClass: def __init__(self, value): self._n = value #第一个字符是单底线的变量_n self.__n = value #前两个字符都是单底线的变量__n def __func(self): #前两个字符都是单底线的函数__func() print (self._n + 1) >>>x = myClass(100) >>>x._n #第一个字符是单底线的变量_n,可以任意存取 100 >>>x.__n #错误,因为__n已经被改名为_myClass__n Traceback (most recent call last): File "<pyshell#376>", line 1, in <module> x.__n AttributeError: 'myClass' object has no attribute '__n' >>> x._myClass__n #正确 100 >>> x.__func() #错误,因为__func()已经被改名为_myClass__func() Traceback (most recent call last): File "<pyshell#378>", line 1, in <module> x.__func() AttributeError: 'myClass' object has no attribute '__func' >>>x._myClass__func() #正确 101
2.类命名空间
类中的所有属性都存储在该类的命名空间(namespace)内。因此,如果在类中存储了一个全局变量的值,此值就会被放置在该类的命名空间内。就算以后此全局变量的值被改变了,类内的该值仍然维持不变。
下列案例设置一个全局变量w = 10,在myClass类中使用storeVar()函数存储此值。当全局变量w的值改变时,myClass类中的值仍然维持不变。
>>> class myClass: w = 10 def storeVar(self, n = w): return n >>> x = myClass() >>> x.storeVar() 10 >>> w = 20 >>> x.storeVar() 10