20 封装

1.封装

面向对象编程有三大特征:封装,继承,多态。
封装:将数据与功能打包写进一个对象中。
针对封装到对象或者类中属性,可以控件对它们的访问,分两步实现,隐藏与开放接口。

2.隐藏属性

Python的Class机制采用双下划线的方法将属性进行变形操作,从而隐藏起来,类中的所有双下划线开头的属性都会在定义阶段检测语法时自动变成 _类名__属性名称 的形式。
class Foo:
    __name = 'kid'         # 变形 _Foo__name

    def __init__(self):
        self.__age = 18    # 变形 _Foo__age

    def __func(self):     # 变形 _Foo__func
        print('from __func run')
print(Foo.__name)    # AttributeError: 类中没有这个属性
obj= Foo()
print(obj.__name)    # AttributeError
原本的名称被进行了变形的处理 __属性名称  变为 _类名__属性名称。
以变形后名名称就可以正常访问了。这种操作没有严格意义上的限制访问,仅只是一种语法意义上的变形。 
print(Foo._Foo__name)    # kid
obj= Foo() 
print(obj._Foo__name)    # kid
obj._Foo__func()         # from __func run
print(Foo.__dict__)
{··· '_Foo__name': 'kid', '_Foo__func': <function Foo.__func at 0x00000000012C7430>,···}
在类内部是可以直接访问双下划线开头的属性,因为在类定义阶段内部双下划线开头的属性统一发生了变形。
class Foo:

    def __func(self):      # 变形 _Foo__func
        print('from __func run')
    def info(self):  
        self.__func()      # 我也变形了嘿嘿
  
 obj= Foo()
 obj.info()               #  from __func run
通过info()来访问 __func。
变形操作只在定义阶段发生一次,在类定义之后的赋值操作,不会变形。
class Foo:
    __x = 1

Foo.school = '桂电'

print(Foo.__dict__)
{···'_Foo__x': 1,  'school': '桂电'···}

3.开发接口

将属性隐藏就是限制类外部内类直接操作,然后再类的内部提供相对应的接口提供外部的间接访问、操作,在接口至上可以附加额外的逻辑来对数据的操作进行严格的控制。
3.1数据接口
class Student:
    def __init__(self, name, age):
        set_info(self, name, age)

    def set_info(self, name, age):
        if type(name) != str:
            return print('名字必须是字符串!')
        if type(age) != int:
            return print('名字必须是数字!')

        self.__name = name
        self.__age = age

stu1 = Student('kid', 18)
stu1.set_info(1, 19)            # 名字必须是字符串!
stu1.set_info('kid', '18')      # 名字必须是数字!
stu1实例化后,stu1调用函数et_info()修改定制了限制。
class Student:

    def set_info(self, name, age):
        if type(name) != str:
            return print('名字必须是字符串!')
        if type(age) != int:
            return print('名字必须是数字!')
        self.__name = name
        self.__age = age
        
    def __init__(self, name, age):
        self.set_info(name, age)    

stu1 = Student('kid', 18)
3.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):          # ATM功能
         self.__card()
         self.__auth()
         self.__input()
         self.__print_bill()
         self.__take_money()

obj=ATM()
obj.withdraw()                  # 调用接口操作每个功能
4.property
property装饰器,将类中函数属性伪装成数据属性,对象在访问特殊属性时就会触发功能的执行,然后将返回值作为本次访问就结果。
class Salary:
    def __init__(self, money):
        self.money = money

    def annual(self):
        return  print(self.money * 12)

job = Salary(6000)
job.annual()
class Salary:
    def __init__(self, money):
        self.money = money

    @property                      # 兄弟带上你的帽子
    def annual(self):
        return print(self.money * 12)

job = Salary(6000)
job.annual                         # 假装自己是一个属性
property装饰器还有两个配套功能。@伪装的函数名称.setter,设置属性,@伪装的函数名称.deleter,删除属性,注意名称一定需要一样。
class Student:
    def __init__(self, name):
        self.__name = name

    @property
    def name(self):
        return self.__name

    @name.setter
    def name(self, name):
        if type(name) != str:
            return print('名字必须是字符串!')
        self.__name = name

    @name.deleter
    def name(self):
        return print('无法删除')

obj = Student('kid')
print(obj.name)
obj.name = 12   # 名字必须是字符串!
del obj.name
kid
名字必须是字符串!
无法删除
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值