对外隐藏内部实现细节和属性,并提供简易访问的接口python
1.为了保证 关键数据的安全性
2.对外部隐藏实现细节,隔离复杂度编程
python中的权限分为两种
1.公开 外界能够直接访问和修改
2.私有 外界不能直接访问和修改,在当前类中能够直接修改和访问缓存
1.第一个层面的封装(什么都不用作):建立类和对象会分别建立两者的名称空间,咱们只能用类名.或者obj.的方式去访问里面的名字,这自己就是一种封装 2.第二个层面的封装:类中把某些属性和方法隐藏起来(或者说定义成私有的),只在类的内部使用、外部没法访问,或者留下少许接口(函数)供外部访问
_名字 都是私有的,原则上是仅供内部调用的,外部依然能够_名字调用(但本意为不要调用!!!)
__名字 设置为私有属性或方法 实质是在加载类时候,把__替换成了 _类名__,外部能够_类名__名字调用(但本意为不要调用)
区别: 不一样于_名字,这种封装在外部单纯属性或方法名不会会被调用
ps:由于python通常不会强制要求程序必须怎么怎么的,
python要想与其余编程语言同样,严格控制属性的访问权限,只能借助内置方法如__getattr__安全
客官,菜(code)来了-->类中对象属性的封装
你好socket
class Person: def __init__(self, id_number, name, age): self.__id_number = id_number self.name = name self.age = age def show_id(self): print(self.__id_number) p = Person("1111111111111", "jack", 29) p.__id_number = "222" print(p.__id_number) p.show_id()
客官,菜(code)又来了-->类中对象方法的封装编程语言
class PC: def __init__(self,price,kind,color): self.price = price self.kind = kind self.color = color def open(self): print("接通电源") self.__check_device() print("载入内核") print("初始化内核") self.__start_services() print("启动GUI") self.__login() def __check_device(self): print("硬件检测1") print("硬件检测2") print("硬件检测3") print("硬件检测4") def __start_services(self): print("启动服务1") print("启动服务2") print("启动服务3") print("启动服务4") def __login(self): print("login....") print("login....") print("login....") pc1 = PC(20000,"香蕉","黄色") # pc1.open() pc1.login()
在python中用双下划线的方式实现隐藏属性(设置成私有的)
类中全部双下划线开头的名称如__x都会自动变造成:_类名__x的形式:函数
类中定义的__x只能在内部使用,如self.__x,引用的就是变形的结果。
这种变形其实正是针对内部的变形,在外部是没法经过__x这个名字访问到的。
在子类定义的__x不会覆盖在父类定义的__x,由于子类中变造成了:_子类名__x,而父类中变造成了:_父类名__x,即双下滑线开头的属性在继承给子类时,子类是没法覆盖的。url
这种机制也并无真正意义上限制咱们从外部直接访问属性,知道了类名和属性名就能够拼出名字:_类名__属性,而后就能够访问了,如a._A__N 变形的过程只在类的定义时发生一次,在定义后的赋值操做,不会变形 在继承中,父类若是不想让子类覆盖本身的方法,能够将方法定义为私有的
python并不会真的阻止你访问私有的属性,模块也遵循这种约定,若是模块中的变量名_private_module以单下划线开头,那么from module import *时不能被导入该变量,可是你from module import _private_module依然是能够导入该变量的设计
ps: 其实不少时候你去调用一个模块的功能时会遇到单下划线开头的(socket._socket,sys._home,sys._clear_type_cache),这些都是私有的,原则上是供内部调用的,做为外部的你,独断独行也是能够用的,只不过显得稍微傻逼一点点
python要想与其余编程语言同样,严格控制属性的访问权限,只能借助内置方法如__getattr__,详见面向对象高级部分。code
提供用于访问和修改的方法
客官,菜(code)来了
""" 这是一个下载器类,须要提供一个缓存大小这样的属性 缓存大小不能超过内存限制 """ class Downloader: def __init__(self,filename,url,buffer_size): self.filename = filename self.url = url self.__buffer_size= buffer_size def start_download(self): if self.__buffer_size <= 1024*1024: print("开始下载....") print("当前缓冲器大小",self.__buffer_size) else: print("内存炸了! ") def set_buffer_size(self,size): #能够在方法中添加额外的逻辑 if not type(size) == int: print("大哥 缓冲区大小必须是整型") else: print("缓冲区大小修改为功!") self.__buffer_size = size def get_buffer_size(self): return self.__buffer_size d = Downloader("葫芦娃","http://www.baicu.com",1024*1024) # 经过函数取修改内部封装的属性 d.set_buffer_size(1024*512) # 经过函数访问内部封装的属性 print(d.get_buffer_size()) print(d.filename) d.start_download()
因而可知 利用好私有属性在类内部中能够被调用的状况 用函数封装好简易的接口,而后外部经过调用它得到对应函数接口里面执行的设计好的对私有属性的操做结果. 这样的方式来实现外部来访问封装的属性!!