封装

一、封装介绍

封装是面向对象三大特性最核心的一个特性

封装<->整合

二、隐藏属性

1.如何隐藏:在属性名前加__前缀,就会实现一个对外隐藏属性效果

# 该隐藏需要注意的问题:
# I:在类外部无法直接访问双下滑线开头的属性,但知道了类名和属性名就可以拼出名字:_类名__属性,然后就可以访问了,如Foo._A__N,
# 所以说这种操作并没有严格意义上地限制外部访问,仅仅只是一种语法意义上的变形。
# class Foo:
#     __x = 1  # _Foo__x
#
#     def __f1(self):  # _Foo__f1
#         print('from test')
#
#
# # print(Foo.__dict__)
# # print(Foo._Foo__x)
# # print(Foo._Foo__f1)

# II:这种隐藏对外不对内,因为__开头的属性会在检查类体代码语法时统一发生变形
# class Foo:
#     __x = 1  # _Foo__x = 1
#
#     def __f1(self):  # _Foo__f1
#         print('from test')
#
#     def f2(self):
#         print(self.__x) # print(self._Foo__x)
#         print(self.__f1) # print(self._Foo__f1)

# III: 这种变形操作只在检查类体语法的时候发生一次,之后定义的__开头的属性都不会变形
class Foo:
    __x = 1  # _Foo__x = 1

    def __f1(self):  # _Foo__f1
        print('from test')

    def f2(self):
        print(self.__x) # print(self._Foo__x)
        print(self.__f1) # print(self._Foo__f1)

Foo.__y=3
print(Foo.__dict__)
print(Foo.__y)

2.为何要隐藏?

定义属性就是为了使用,所以隐藏并不是目的

# I、隐藏数据属性"将数据隐藏起来就限制了类外部对数据的直接操作,然后类内应该提供相应的接口来允许类外部间接地操作数据,接口之上可以附加额外的逻辑来对数据的操作进行严格地控制:
>>> class Teacher:
...     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,name,age): #对外提供设置老师信息的接口,并附加类型检查的逻辑
...         if not isinstance(name,str):
...             raise TypeError('姓名必须是字符串类型')
...         if not isinstance(age,int):
...             raise TypeError('年龄必须是整型')
...         self.__name=name
...         self.__age=age
... 
>>>
>>> t=Teacher('lili',18)
>>> t.set_info(‘LiLi','19') # 年龄不为整型,抛出异常
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "<stdin>", line 11, in set_info
TypeError: 年龄必须是整型
>>> t.set_info('LiLi',19) # 名字为字符串类型,年龄为整形,可以正常设置
>>> t.tell_info() # 查看老师的信息
姓名:LiLi,年龄:19

# II、隐藏函数/方法属性:目的的是为了隔离复杂度
>>> 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()
...
>>> obj=ATM()
>>> obj.withdraw()
posted @ 2020-04-08 20:52  aksas  阅读(165)  评论(0编辑  收藏  举报