一。python的封装机制
面向对象的编程语言都有三个显著的特征。封装, 继承, 多态,所谓封装可以简单的理解为。在设计类时刻意的将属性和方法隐藏在类的内部。 这样在使用此类时。就无法直接以类对象.属性名或者类对象.方法(参数名)调用这些属性或方法。 而只能通过隐藏的类方法间接的操作这些隐藏的属性和方法。
二。封装的好处
- 保证了类内部数据结构的完整性。因为使用类的用户无法直接看到类中的数据结构。 只使用类允许公开的数据。 避免了外部对内部数据的影响。
- 对一个类实现良好的封装。用户只能使用类暴露出来的方法访问数据。只需要在这些暴露的方法中加入适当的控制逻辑。从而实现用户对类中属性和方法的不合理操作。
三 python的封装
python类中的变量和函数不是公有的就是私有的;区别如下
- public公有属性的类变量和类函数。 在类的外部。类内部以及子类都可以访问
- private私有属性的类变量和类函数。只能在本类的内部使用。类的外部和子类无法访问
即便是这样python并没有提供public、private这样的修饰符。为了实现类的封装。采取了如下方法
- 默认情况下。类中的变量和方法都是公有的。他们的名称前没有下划线(_)
- 如果类的函数或者变量以双下划线(__)开头。则表示该变量或者该函数为私有变量或者私有函数。
- 还有一种约定俗成的写法以单下划线(_)定义的属性和方法,这种写法通常也被视为私有属性或私有方法。虽然他们可以通过类对象正常访问但是还是要遵守其规则
class Person:
def setNumber(self, a):
if a < 20:
return ValueError("被设置的值必须大于10")
self.__number = a
def getNumber(self):
return self.__number
number = property(getNumber, setNumber)
def __getNumber(self):
print(self.__number)
def getName(self):
return self.__name
def setName(self, b):
if isinstance(b, str):
self.__name = b
name = property(getName, setName)
a = Person()
a.number = 21
print(a.number)
a.name = "小王"
print(a.name)
21
小王
我们不难发现a对象的name和number是被隐藏起来的。但与此同时提供了可操作该属性的方法。而这些方法是公有的。不仅如此当操作不规范时。因为增加了控制逻辑所以会抛出异常。
通过对类进行封装。使用户只能通过暴露出来的方法访问其中的属性。还可以通过一些适当的设计可以避免用户对对象的不合理操作。从而提高了类的可维护性和安全性。
此外类中的私有属性和方法不能在类的外部使用
class Person:
def setNumber(self, a):
if a < 20:
return ValueError("被设置的值必须大于10")
self.__number = a
def getNumber(self):
return self.__number
number = property(getNumber, setNumber)
def __getNumber(self):
print(self.__number)
def getName(self):
return self.__name
def setName(self, b):
if isinstance(b, str):
self.__name = b
name = property(getName, setName)
a = Person()
a.__getNumber()
Traceback (most recent call last):
File "/Users/apple/Documents/重要文件/python3/python21.py", line 25, in <module>
a.__getNumber()
AttributeError: 'Person' object has no attribute '__getNumber'