封装
什么是封装?
装指的是把属性装进一个容器
封指的是隐藏的意思,但是这种隐藏式对外不对内的
为何要封装?
封装不是单纯意义的隐藏
封装数据属性的目的:将数据属性封装起来,类外部的使用就无法直接操作该数据属性了
需要类内部开一个接口给使用者,类的设计者可以在接口之上附加任意逻辑,从而严格
控制使用者对属性的操作
封装函数属性的目的:隔离复杂度
如何封装?
只需要在属性前加上__开头,该属性就会被隐藏起来,该隐藏具备的特点:
1. 只是一种语法意义上的变形,即__开头的属性会在检测语法时发生变形_类名__属性名
2. 这种隐藏式对外不对内的,因为在类内部检测语法时所有的代码统一都发生的变形
3. 这种变形只在检测语法时发生一次,在类定义之后新增的__开头的属性并不会发生变形
4. 如果父类不想让子类覆盖自己的属性,可以在属性前加__开头
如下:
#一般玩法
class Foo: __x=111 #_Foo__x def __init__(self,m,n): self.__m=m # self._Foo__m=m self.n=n def __func(self): #_Foo__func print('Foo.func') def func1(self): print(self.__m) #self._Foo__m print(self.__x) #self._Foo__x
print(Foo.__dict__) print(Foo._Foo__x) print(Foo._Foo__func) 结果: {'__module__': '__main__', '_Foo__x': 111, '__init__': <function Foo.__init__ at 0x000001DFFDE599D8>, '_Foo__func': <function Foo.__func at 0x000001DFFDE59AE8>, 'func1': <function Foo.func1 at 0x000001DFFDE59B70>, '__dict__': <attribute '__dict__' of 'Foo' objects>, '__weakref__': <attribute '__weakref__' of 'Foo' objects>, '__doc__': None} 111 <function Foo.__func at 0x000001DFFDE59AE8>
#常用玩法 class Foo: def __f1(self): #_Foo__f1 print('Foo.f1') def f2(self): print('Foo.f2') self.__f1() #self._Foo__f1 class Bar(Foo): def __f1(self): #_Bar__f1 print('Bar.f1') obj=Bar() obj.f2() 结果: Foo.f2 Foo.f1
# 封装数据属性的真实意图 class People: def __init__(self,name,age): self.__name=name self.__age=age def tell_info(self): print('<name:%s age:%s>' %(self.__name,self.__age)) def set_info(self,new_name,new_age): if type(new_name) is not str: print('名字必须是str类型傻叉') return if type(new_age) is not int: print('年龄必须是int类型傻叉') return self.__name=new_name self.__age=new_age def clear_info(self): del self.__name del self.__age obj=People('egon',18) obj.tell_info()
obj.set_info('egon',20)
obj.tell_info()
结果: <name:egon age:18>
<name:egon age:20>
# 封装函数属性的真实意图 class ATM: def __card(self): print('插卡') def __auth(self): print('用户认证') def __input(self): print('输入取款金额') def __print_bill(self): print('打印账单') def __take_money(self): print('取款') def withdraw(self): self.__card() self.__auth() self.__input() self.__print_bill() self.__take_money() a=ATM() a.withdraw()
结果:
插卡
用户认证
输入取款金额
打印账单
取款
封装主要针对用户的,而非开发者
目的: 有些是开发者需要扩展时修改的数据,避免用户随意操作。