zoukankan      html  css  js  c++  java
  • 封装||property

    封装

    封装:主要是指在类的定义阶段将,以__开头的属性名进行变形.。例如:__name ==> _People__name

    封装的主要特点

    1.在类外部无法直接__name,想要在外部调用可以使用_People__name
    2.在类内部可以直接使用__name
    3.子类无法覆盖父类__开头的属性

    解释特点3的例子:

    class Foo:
        def __func(self): # _Foo_func
            print('from foo')
    
    class Bar(Foo):
        def __func(self): # _Bar_func
            print('form bar')
    
    b = Bar()
    b.func()

    由上可以看出函数属性名在经过变形之后,子类与父类的函数名不相同,所以子类无法覆盖父类__开头的属性

    封装的时候应注意的问题

    1.所谓的隐藏并不是真正的隐藏,可以通过_People__name来获取

    2.想要隐藏属性,就要在类的定义阶段进行隐藏,只发生一次

    3.在继承中,父类如果不想让子类覆盖自己的方法,可以将方法定义为私有的

    解释问题一的例子

    class B:
         __x = 1
    
    print(_B__x)

    解释问题二的例子

    class B:
        __x = 1
    
        def __init__(self,name):
            self.__name = name
    
    B.__y = 2
    print(B.__dict__)
    print(B.__y)

    第一次打印的是:

    {'__module__': '__main__', '_B__x': 1, '__init__': <function B.__init__ at 0x000002412D07BA60>, '__dict__': <attribute '__dict__' of 'B' objects>, '__weakref__': <attribute '__weakref__' of 'B' objects>, '__doc__': None, '__y': 2}

    由此可以看出想要隐藏属性,只能在类定义的时候进行隐藏

    解释问题三的例子

    class A:
        def __foo(self): # _A__foo
            print('A.foo')
    
        def bar(self):
            print('A.bar')
            self.__foo() #self._A_foo()
    
    class B(A):
        def __foo(self): # _B__foo
            print('B.foo')
    
    b = B()
    b.bar()

    封装的意义

    封装数据属性的意义:明确区分内外,控制外部对的隐藏属性的操作行为

    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("年龄必须是整数类型")
    
            self.__name = name
            self.__age = age
    
    
    p = People('yang',18)
    # p.tell_info()
    
    p.set_info('11',19)
    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()
    
    print(ATM.__dict__)
    a=ATM()
    a.withdraw()

    property: 

    @property 主要是将将函数属性伪装成数据属性,是一种特殊的属性,访问它时会执行一段功能(函数)然后返回值

    • @property     查看 必须要有返回值   print(p.name)  name 是函数属性 不是数据属性 伪装成 数据属性
    • @name.setter  修改                 p.name='alex'
    • @name.deleter 删除                 del p.name

      总结:通过计算得来的方法 可以通过@property 伪装成数据属性 

    '''
    例一:BMI指数(bmi是计算而来的,但很明显它听起来像是一个属性而非方法,如果我们将其做成一个属性,更便于理解)
    成人的BMI数值:
    过轻:低于18.5
    正常:18.5-23.9
    过重:24-27
    肥胖:28-32
    非常肥胖, 高于32
    体质指数(BMI)=体重(kg)÷身高^2(m)
    EX:70kg÷(1.75×1.75)=22.86
    '''
    
    class People:
        def __init__(self,name,height,weight):
            self.name = name
            self.weight = weight
            self.height = height
    
        @property
        def bmi(self):
            return self.weight / (self.height ** 2)
    
    p = People('yang',1.78,61)
    print(p.bmi)
    # p.bmi = 33 #报错
    
    
    
    class People:
        def __init__(self,name):
            self.__name = name
    
        @property
        def name(self):
            # print('getter')
            return self.__name
    
        @name.setter
        def name(self,val):
            # print('setter')
            if not  isinstance(val,str):
                print('名字必须是字符串类型')
                return
            self.__name = val
    
        @name.deleter
        def name(self):
            print("不可以被删除")
    
    
    
    p = People('egon')
    # print(p.get_name())
    
    # p.name = 'EGON'
    # print(p.name)
    del p.name
  • 相关阅读:
    第十四周学习进度
    团队十日冲刺17
    团队十日冲刺16
    找水王
    搜狗输入法评价
    团队十日冲刺15
    团队十日冲刺14
    团队十日冲刺13
    团队十日冲刺12
    团队十日冲刺11
  • 原文地址:https://www.cnblogs.com/Mryang123/p/8602555.html
Copyright © 2011-2022 走看看