封装,抛开面向对象不说,装就是将小猫,小狗装进麻袋,封就是将麻袋封上口。
在面向对象中,这个麻袋就是类或者对象,类和对象这两个麻袋内部装了数据属性和函数属性,那么对于类和对象来说,封就是将属性隐藏起来,外部无法使用。
那么如何完成’封‘呢?
python是不依赖语言特性去封装数据,而是通过遵循一定的数据属性和函数的属性的命名约定达到封的效果
约定一:任何一单下划线开头的名字都应该是内部的,私有的。
class People:
_star = 'earth'
def __init__(self,id,name,age,salary):
self.id = id
self.name = name
self._age = age
self._salary = salary
def _get_id(self):
print('我是私有方法,我的ID是%s'%(self.id))
print(People._star)
p1 = People('12345','alex',28,10)
print(p1._age,p1._salary)
p1._get_id()
运行结果:
很明显,虽然类和对象的数据属性都加了下划线,外部不是可以调用的,在这里确实可以调用?
其实,python是不会真的阻止程序员访问私有属性,仅仅是自觉遵循这个约定而已,不带有强制性,外部可以调用,但是对编程的人来讲,还是自觉的遵循约定,不要调用私有的属性,以免出项BUG。
同样的模块也遵循这个约定,如果模块名以单下划线开头,那么from module import*时不能被导入,但是from module import __pivate_module依然是可以被导入的。
约定二:双下划线开头的名字。
class People:
__star = 'earth'
def __init__(self,id,name,age,salary):
self.id = id
self.name = name
self.__age = age
self._salary = salary
def tell_star(self):
print('%s from XXXX %s'%(self.name,self.__star))
p1 = People('12345','alex',18,12)
#print(p1.__star) 直接访问是会报错的。
#1,第一种方法访问
p1.tell_star()
#2,第二种方法访问
print(p1._People.__star)
第一种方法:你把某个属性在开始的时候设置成私有的,但是后来你发现这个属性应该是开放的,解决方法就是在类里写一个访 问函数,去内部调用私有属性。这是一个好方法,但是如果滥用,就需要很多写访问函数,将类搞的千疮百孔。
第二种方法:在python中,如果某个属性加了双下划线,那么类中就会自动进行重名操作,_类名.__属性名。这样直接访问就会 报错,因为找不到该属性。