标签:card raise ini atm 打印 数据隐藏 基本概念 字符 info
面向对象编程有三个特性:封装、继承、多态,其中封装特性极为重要。封装指的是把数据与功能整合到一起。当然针对封装到对象或者类中的属性,我们还可以严格控制对它们的访问,分两步实现:隐藏和开放接口
Python
的机制Class
机制采用双下划线开头的方式将属性隐藏起来(设置成私有的),但其实这仅仅只是一种变形操作,类中所有双下划线开头的属性都会在类定义阶段、检测语法时自动变成_类名__属性名
的形式
class Foo:
__N = 0 # 变形为_Foo__N
def __init__(self): # 定义函数时,会检测函数语法,所以__开头的属性也会变形
self.__x = 10 # 变形为self._Foo__x
def __f1(self): # 变形为_Foo__f1
print("__f1 run")
def f2(self): # 定义函数时,会检测函数语法,所以__开头的属性也会变形
self.__f1() # 变形为self._Foo__f1()
print(Foo.__N) # 报错AttributeError:类Foo没有属性__N
obj = Foo()
print(obj.__x) # 报错AttributeError:对象obj没有属性__x
这种变形需要主要的问题是:
_类名__属性
,然后就可以访问了,如Foo._A__N
,所以说这种操作并没有严格意义上地限制外部访问,仅仅只是语法意义上的变形>>> Foo.__dict__
mappingproxy({..., ‘_Foo__N‘: 0, ...})
>>> obj.__dict__
{‘_Foo__x‘: 10}
>>> Foo._Foo__N
0
>>> obj._Foo__x
10
>>> obj._Foo__N
0
self.__f1()
,因为在类定义阶段内部双下划线的属性统一发生了变形>>> obj.f2()
__f1 run
>>> Foo.__M=100
>>> Foo.__dict__
mappingproxy({..., ‘__M‘: 100,...})
>>> Foo.__M
100
>>> obj.__y=20
>>> obj.__dict__
{‘__y‘: 20, ‘_Foo__x‘: 10}
>>> obj.__y
20
定义属性就是为了使用,所以隐藏并不是目的
将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制
class Teacher:
def __oct__(self,name,age): # 将名字和年纪都隐藏起来
self.__name = name
self.__age = age
def tell_info(self): # 对外提供访问老师信息的接口
print("姓名:{},年龄:{}".format(self.__name,self.__age))
def set_info(self,name,age): # 对外提供设置老师信息的接口,并附加类型检查的逻辑
if not isinstance(name,str):
raise TypeError("姓名必须为字符串类型")
if not isinstance(age,int):
raise TypeError("年龄必须是整型")
self.__name = name
self.__age = age
teacher_obj = Teacher()
teacher_obj.set_info("LiLi","19")
"""
TypeError: 年龄必须是整型
"""
teacher_obj.set_info("lili",18)
teacher_obj.tell_info()
"""
姓名:lili,年龄:18
"""
目的是为了隔离复杂度,例如ATM程序的取款功能,该功能有很多其他的功能组成,比如插卡、身份认证、输入金额、打印小票、取钱等,而对使用者来说,只需要开发取款这个功能接口即可,其余功能我们都可以隐藏起来
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 witudraw(self): # 取款功能
self.__card()
self.__auth()
self.__input()
self.__print_bill()
self.__take_money()
ATM_obj = ATM()
ATM_obj.witudraw()
总结隐藏属性与开放接口,本质就是为了明确地区分开内外,类内部可以修改封装地东西而不影响外部调用者的代码,使用者均无需改变代码。这就提供一个良好的合作基础,只要接口这个基础约定不变,则代码的修改不足为虑
标签:card raise ini atm 打印 数据隐藏 基本概念 字符 info
原文地址:https://www.cnblogs.com/zhuyouai/p/12663234.html