• Python3 从零单排18_封装


      隐藏属性
    # 申明类时,数据属性或者函数属性,在属性名称前加上两个下划线,就实现了属性隐藏,但在python里不存在绝对的隐藏,它只是在申明的时候定义了它的调用方式。
    class A:
        __country = "china"
    
        def __def(self):
            print(self.__country)
    
    
    a = A()
    print(a.__country)  # 报错,这是隐藏属性
    print(a._A__country)  # 对的,python里不会绝对隐藏,只是在类命名的时候定义了新的访问方式,需要在隐藏变量名前加 "_类名" 就可以访问
    print(A.__dict__)  # 可以看到在类A的属性字典里有一个kv是'_A__country': 'china',隐藏的函数属性也一样的道理
    
    # 当然python只是没有绝对隐藏,但是如果加上了隐藏属性,一般不会像上面那样去访问,那这个有什么用呢?
    # 1.防止属性被改写   2.防止类内部在调用属性的时候调用到别的类的属性
    class A:
        def func1(self):
            print("i am func1 from A")
    
        def __func2(self):
            print("i am func2 from A")
    
        def func3(self):
            print("i am func3 from A")
            self.func1()  # b调用时,这里实际是 b.func1(),那么他先会在B类里找func1,所以这里会打印("i am func1 from B")
            self.__func2()  # b调用时,这里实际是 b._A__func1(),那么找到的就是A类里的__func2,所以这里会打印("i am func2 from A")
    
    
    class B(A):
        def func1(self):
            print("i am func1 from B")
    
        def __func2(self):  # 这里并不是改写父类A的__func2,因为这里已经变成了,_B__func2
            print("i am func2 from A")
    
    
    b = B()
    b.func3()
    封装数据属性:明确的区分内外,控制外部对隐藏的属性的操作行为
    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,name,age):
            if not isinstance(name,str):
                print('名字必须是字符串类型')
                return
            if not isinstance(age,int):
                print('年龄必须是数字类型')
                return
            self.__name=name
            self.__age=age
    
    p=People('egon',18)
    
    # p.tell_info()
    
    # p.set_info('EGON',38)
    # p.tell_info()
    
    # p.set_info(123,38)
    p.set_info('egon','38')
    p.tell_info()
    
    
    封装方法隔离复杂度
    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()
    property 将函数属性变成数据属性,但只是像数据属性,并不是真的数据属性,在重新赋值的时候会报错。
    
    
    class People:
        def __init__(self,name,weight,height):
            self.name=name
            self.weight=weight
            self.height=height
    
        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    
    p=People('xg',60,168)
    # print(p.bmi)
    # p.bmi=3333 #报错AttributeError: can't set attribute
    
    # 但是有一些方法可以修改和删除这些属性。
    
    
    class A:
        def __init__(self, name):
            self.__name = name
    
        @property
        def name(self):
            return self.__name
    
        @name.setter
        def name(self, name):  # 修改被property装饰的函数属性,直接 a.name = new_name 即可
            self.__name = name
    
        @name.deleter
        def name(self):  # 删除 a.name ,直接 del a.name 即可
            print("不可以删除")
    
    
    a = A("xg")
    print(a.name)
    a.name = "XG"
    print(a.name)
    del a.name
    print(a.name)
    
    
    
     
     
     
  • 相关阅读:
    python类组合
    python 反射 (自省)
    继承 继承 多态
    与属性的深入交流
    与对象的第一次相遇
    MySQL 主从复制
    Redis 配置项
    Redis Cluster 部署
    网络协议和管理
    字符串
  • 原文地址:https://www.cnblogs.com/znyyy/p/10144535.html
Copyright © 2020-2023  润新知