封装||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
原文地址:https://www.cnblogs.com/Mryang123/p/8602555.html