1.先看隐藏。
在python中用两个下划线开头的方式将属性隐藏起来。
注意:这种只是语法的变形,在读到有以__开的的函数时,会自动将名称变成 ”_类名__属性”这种格式,所以在函数外部是无法通过 __属性 找到这个属性的。
class Foo:
__N=111111 #将属性隐藏起来 #在定义阶段会变成 _Foo__N
def __init__(self,name):
self.__Name = name
def __f1(self): #同理隐藏这个函数 #在定义阶段会变成 _Foo__f1
print('这里是f1')
def f2(self):
self.__f1() #在类内部是可以用__f1访问到隐藏属性的。 #在定义阶段会变成 self._Foo__f1
#
f=Foo('yxwang') #实例化一个对象。
# f.__N #在类的外部是无法通过__N的方法访问到隐藏属性的。
f.f2() #会打印出“这里是f1”,因为f2是类内部的方法,f2是可以调到隐藏属性__f1的。
2.再来看封装
(1)封装数据属性:
隐藏属性不是目的,隐藏属性是为了直接在内部提供一个外部调用着使用的接口。这样就可以通过这个接口对属性实现控制。
例子:
class People:
def __init__(self,name,age):
self.__Name=name
self.__Age=age
def tell_info(self): #定义一个返回结果的格式。
print('<名字:%s 年龄:%s>' %(self.__Name,self.__Age))
def set_info(self,x,y):
if not isinstance(x,str): #加上判断条件,判断用户输入的是不是字符串类型
raise TypeError('%s must be str' %x) #定义返回的错误。
if not isinstance(y,int): #判断用户输入的第二个参数 是不是数字类型。
raise TypeError('%s must be int' %y)
self.__Name=x
self.__Age=y
p=People('egon',18)
p.tell_info() #获取一下格式化的数据
#p.set_info('Egon','19') #当第二个参数为字符串的时候会报错。 因为不匹配第二个参数为数字的条件
p.set_info('Egon',19)
p.tell_info() #再次获取一下返回结果
(2)封装函数属性。
是为了降低复杂度,同时也提高了安全性。
比如,用户取款,取款在程序中有 插卡 密码认证 取款金额判断,等等一些负责的功能。
但是对于用户来说只需要知道取款就可以了。其余的负责功能就可以隐藏起来了。
例子:
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()