Python封装机制及实现方法
简单的理解封装(Encapsulation),即在设计类时,刻意地将一些属性和方法隐藏在类的内部,这样在使用此类时,将无法直接以“类对象.属性名”(或者“类对象.方法名(参数)”)的形式调用这些属性(或方法),而只能用未隐藏的类方法间接操作这些隐藏的属性和方法。
就好比使用电脑,我们只需要学会如何使用键盘和鼠标就可以了,不用关心内部是怎么实现的,因为那是生产和设计人员该操心的。
那么,类为什么要进行封装,这样做有什么好处呢?注意,封装绝不是将类中所有的方法都隐藏起来,一定要留一些像键盘、鼠标这样可供外界使用的类方法。
首先,封装机制保证了类内部数据结构的完整性,因为使用类的用户无法直接看到类中的数据结构,只能使用类允许公开的数据,很好地避免了外部对内部数据的影响,提高了程序的可维护性。
除此之外,对一个类实现良好的封装,用户只能借助暴露出来的类方法来访问数据,我们只需要在这些暴露的方法中加入适当的控制逻辑,即可轻松实现用户对类中属性或方法的不理操作。
并且,对类进行良好的封装,还可以提高代码的复用性。
Python 类如何进行封装?
和其它面向对象的编程语言(如 C++、Java)不同,Python 类中的变量和函数,不是公有的(类似 public 属性),就是私有的(类似 private),这 2 种属性的区别如下:
public:公有属性的类变量和类函数,在类的外部、类内部以及子类(后续讲继承特性时会做详细介绍)中,都可以正常访问;
private:私有属性的类变量和类函数,只能在本类内部使用,类的外部以及子类都无法使用。
但是,Python 并没有提供 public、private 这些修饰符。为了实现类的封装,Python 采取了下面的方法:
默认情况下,Python 类中的变量和方法都是公有(public)的,它们的名称前都没有下划线(_);
如果类中的变量和函数,其名称以双下划线“__”开头,则该变量(函数)为私有变量(私有函数),其属性等同于 private。
除此之外,还可以定义以单下划线“_”开头的类属性或者类方法(例如 _name、_display(self)),这种类属性和类方法通常被视为私有属性和私有方法,虽然它们也能通过类对象正常访问,但这是一种约定俗称的用法,初学者一定要遵守。
注意,Python 类中还有以双下划线开头和结尾的类方法(例如类的构造函数__init__(self)),这些都是 Python 内部定义的,用于 Python 内部调用。我们自己定义类属性或者类方法时,不要使用这种格式。
例如,如下程序示范了 Python 的封装机制:
class CLanguage :
def setname(self, name):
if len(name) < 3:
raise ValueError('名称长度必须大于3!')
self.__name = name
def getname(self):
return self.__name
#为 name 配置 setter 和 getter 方法
name = property(getname, setname)
def setadd(self, add):
if add.startswith("http://"):
self.__add = add
else:
raise ValueError('地址必须以 http:// 开头')
def getadd(self):
return self.__add
#为 add 配置 setter 和 getter 方法
add = property(getadd, setadd)
#定义个私有方法
def __display(self):
print(self.__name,self.__add)
clang = CLanguage()
clang.name = "C语言中文网"
clang.add = "http://c.biancheng网站站点" rel="nofollow" />
C语言中文网 http://c.biancheng网站站点" rel="nofollow" />
#尝试调用私有的 display() 方法
clang.__display()
这会导致如下错误:
Traceback (most recent call last):
File "D:\python3.6\1.py", line 33, in <module>
clang.__display()
AttributeError: 'CLanguage' object has no attribute '__display'
那么,类似 __display() 这样的类方法,就没有办法调用了吗?并非如此,读者在了解《Python封装实现原理》之后,就可以轻松搞定它。